Hibernate抓取策略

抓取策略(fetching strategy) 是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略。


例如,经典的班级对学生是一对多关联
(1)单端关联(一对一,一对多)(两种策略 select和join)
如果没有配置抓取策略,默认的fetch=”select”,即:另外发送一条 SELECT 语句抓取当前对象的关联实体或集合
Student stu = (Student) session.load(Student.class, 1);
System.out.println(stu.getName());
System.out.println(stu.getClasses().getName());

看执行后发的SQL语句:
Hibernate:select student0_.id as id0_0_, student0_.name as name0_0_, student0_.classesid as classesid0_0_ from t_student student0_ where student0_.id=?
班级0学生0
Hibernate: select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes classes0_ where classes0_.id=?
班级0
从发的SQL语句可以看出,第一条语句是通过students表来查询的,
当我们想去加载它的关联对象classes时,发出第二条语句,是从classes表里查寻得,

如果我设置抓取策略为join,即:

<many-to-one name="classes" column="classesid" fetch="join"></many-to-one>

执行之后,你会发现发出的SQL语句:
Hibernate: select student0_.id as id0_1_, student0_.name as name0_1_, student0_.classesid as classesid0_1_, classes1_.id as id1_0_, classes1_.name as name1_0_ from t_student student0_ left outer join t_classes classes1_ on student0_.classesid=classes1_.id where student0_.id=?
班级0学生0
班级0
fetch=”join”的意思是 :Hibernate通过 在SELECT语句使用OUTER JOIN(外连接)来 获得对象的关联实例或者关联集合
你看我们上面发出的SQL语句,就是个左外连接查询,把学生对应得班级也加载了,所以,它的lazy就失效了。

(2)集合上的抓取策略:(有三种策略,select,join,subselect)
Classes classes = (Classes) session.load(Classes.class, 1);
System.out.println(classes.getName());
for(Iterator iter = classes.getStudents().iterator();iter.hasNext();){
Student stu = (Student) iter.next();
System.out.println(stu.getName());
}
如果没有配置抓取策略,默认的fetch=”select”,
Hibernate: select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes classes0_ where classes0_.id=?
班级0
Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id0_0_, students0_.name as name0_0_, students0_.classesid as classesid0_0_ from t_student students0_ where students0_.classesid=?
班级0学生5
班级0学生1
默认发出两条select语句。

当设置抓取策略fetch=”join”

<set name="students" inverse="true" fetch="join">

Hibernate: select classes0_.id as id1_1_, classes0_.name as name1_1_, students1_.classesid as classesid3_, students1_.id as id3_, students1_.id as id0_0_, students1_.name as name0_0_, students1_.classesid as classesid0_0_ from t_classes classes0_ left outer join t_student students1_ on classes0_.id=students1_.classesid where classes0_.id=?
班级0
班级0学生7
班级0学生3
会发现只发出一条外连接语句,加载它的关联实体,此时,lazy也失效了。

如果设置抓取策略为:

<set name="students" inverse="true" fetch="subselect">

subselect抓取:如果要查询关联集合的内容。会查询之前已经查出的对象的所有关联集合。(Category对应了多个Book)如果查询了(”文学”,”历史”);那么在使用(lazy=true)”文学”或”历史”的集合对象(”所对应的书籍信息”).会将(“文学”和”历史”)的书籍信息一起查询。如果lazy=false;在查询“多个分类时”会将所有分类的书籍信息一起查询。

批量抓取 其实是对查询抓取的优化方案(select) 使用单条sql语句获得一批对象 实例或集合
举例如下

//batch-size属性,可以批量加载实体类,
//每5次做一次查询
<set name="students" batch-size="5">  

最后的sql语句末尾where就可能是这样

where students0_.class_id in (?, ?, ?, ?, ?)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值