抓取策略是表与表之间的关联之间才能体现出来的, 这里介绍一对多跟多对一的情况, 因为多对多可以看成是两个一对多, 一对一也是一对多里面的一种特殊情况
多对一的单端抓取:
"Emp.hbm.xml"配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rl.hiber.model">
<class name="Emp" table="t_emp">
<id name="empNo" column="emp_no">
<generator class="native"></generator>
</id>
<property name="ename"></property>
<property name="birthday"></property>
<property name="gender"></property>
<property name="address"></property>
<!-- 指定多对一的关联映射
name: 多的一端中定义的一的一端的属性, 也就是team
column: 多的一端中的外键, 也就是一的一端中的主键, t_id
这个外键必须跟team.hbm.xml指定的外键一样, 如果两个column的名称不一样则相当于有两个外键就冲突了
fetch: 抓取策略, 一般选择默认(select)即可
-->
<many-to-one name="team" column="t_id" fetch="select"/>
</class>
</hibernate-mapping>
测试代码:
/**
* 多对一的单端抓取
* 默认情况下在配置文件Emp.hbm.xml文件的fetch属性的值是select
* load()是有延迟加载效果的
* 也就是说当fetch=select时是分步抓取的, 当fetch=join时是急加载(使用连接查询)
* 所以在开发中更倾向于使用fetch=select
*/
@Test
public void fetch1() {
Session session = HibernateUtil.getSessoion();
try {
Emp emp = (Emp) session.load(Emp.class, 1);
//当fetch=select/join时发出sql语句
System.out.println(emp);
Team team = emp.getTeam();
//当fetch=select时发出sql, fetch=join时不发出sql语句
System.out.println(team);
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeResource(session);
}
}
一对多的抓取:
一的一端时单一对象的查询:
package com.rl.hiber.test;
import java.util.Set;
import org.hibernate.Session;
import org.junit.Test;
import com.rl.hiber.model.Emp;
import com.rl.hiber.model.Team;
import com.rl.hiber.utils.HibernateUtil;
public class TestHibernate2 {
/**
* fetch=select跟一对多一样
* fetch=join跟一对多一样
* fetch=subSelect在单端抓取时跟fetch=select一样
*/
@Test
public void fetch1() {
Session session = HibernateUtil.getSessoion();
try {
Team team = (Team)session.load(Team.class, 1);
System.out.println(team);
Set<Emp> emps = team.getEmps();
for(Emp emp: emps){
System.out.println(emp);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeResource(session);
}
}
}
"Team.hbm.xml"配置文件的修改:
一的一端是多个对象的查询:
fetch=select的情况:
@Test
public void fetch2() {
Session session = HibernateUtil.getSessoion();
try {
String hql = "from Team";
Query query = session.createQuery(hql);
//发出sql
List<Team> tList = query.list();
for(Team t: tList){
System.out.println(t);
Set<Emp> emps = t.getEmps();
//发出sql
for(Emp e: emps){
System.out.println(e);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeResource(session);
}
}
fetch=join的情况: 同fetch=select
fetch=subSelect的情况:
/**
* fetch=subSelect只有在子查询下才有意义
*/
@Test
public void fetch3() {
Session session = HibernateUtil.getSessoion();
try {
String hql = "from Team";
Query query = session.createQuery(hql);
//发出sql
List<Team> tList = query.list();
for(Team t: tList){
System.out.println(t);
Set<Emp> emps = t.getEmps();
//发出子查询的sql(把所有球队的所有球员都查询出来)
for(Emp e: emps){
System.out.println(e);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeResource(session);
}
}