hibernate提供了两类检索策略:类级别的懒加载,集合的懒加载
本文采用前篇博客的实体类和映射文件,并设置Parent.hbm.xml中class元素的lazy=false
<class name="Parent" lazy="false">
集合的懒加载主要在一对多中一方实体映射文件的set元素中设置,Parent.hbm.xml如下:
为节约篇幅,省略property等元素
<hibernate-mapping package="cn.sina.bean">
<class name="Parent" table="lazy_parent" lazy="false">
<set name="childrens" lazy="true">
<key column="pid"/>
<one-to-many class="Children"/>
</set>
</class>
</hibernate-mapping>
同样的,本文使用load方法进行测试,代码如下:
@Test
public void testLazy(){
Parent parent = (Parent) session.load(Parent.class, 1);
System.out.println(Hibernate.isInitialized(parent.getChildrens()));
}
输出:
Hibernate:
select
parent0_.pid as pid1_0_,
parent0_.name as name1_0_
from
lazy_parent parent0_
where
parent0_.pid=?
false
可以看到发出的sql只查询了parent表,isInitialized的返回值也是false,说明set元素的lazy=true时,确实发生了懒加载,以下将不测试lazy=false的情况,请读者自行测试(只改为lazy=false即可),着重测试lazy=extra
lazy=extra
extra表示hibernate将尽可能晚的懒加载
<set name="childrens" lazy="extra">
如果我们只是想获取set集合的size,那么extra就会起作用,通过代码说明:
@Test
public void testLazy(){
Parent parent = (Parent) session.load(Parent.class, 1);
System.out.println(parent.getChildrens().size());
}
输出为:注意看第二条sql
Hibernate:
select
parent0_.pid as pid1_0_,
parent0_.name as name1_0_
from
lazy_parent parent0_
where
parent0_.pid=?
Hibernate:
select
count(cid)
from
lazy_children
where
pid =?
2
说明调用size()只发出count(id)的sql
类似的还有contains()和isEmpty(),其中isEmpty()和size()发出的是同一条sql,下面看看contains()的sql
测试代码:
@Test
public void testLazy(){
Parent parent = (Parent) session.load(Parent.class, 1);
Children children = new Children();
children.setId(2);
children.setName("cds");
System.out.println(parent.getChildrens().contains(children));
}
注意,我的数据库中id为2的记录,name不为cds,这主要和hibernate发出的sql有关
输出只看一条:
select
1
from
lazy_children
where
pid =?
and cid =?
true
可以看到这用外键做了查询
以上就是集合的检索策略。