您的位置:首页 > 数据库

Hibernate上路_17-检索策略

2013-11-19 16:55 513 查看
hibernate查询优化。

1.立即检索、延时检索:

查询方法get和load的区别:

1)get立即检索;load延迟检索。
2)load检索策略可以通过hbm文件进行配置的,默认是延迟检索lazy="true"。

<hibernate-mapping package="cn.cvu.hibernate.domain">
<class name="PojoUser" table="tb_user" select-before-update="true" lazy="false">

3)代理对象何时初始化(成为实例对象):

(1)getClass() 、getId() 不会进行初始化
(2)当调用 class和id 之外其它属性的get方法时,进行初始化
(3)可以通过工具类Hibernate.initialize(proxy); 对代理对象手动初始化

2.类级别检索、关联级别检索策略:

1)类级别和关联级别的区分:

//通过session的get/load直接得到类的实例
PojoUser user = (PojoUser) session.get(PojoUser.class, 2);	//类级别的检索

//由类实例的get方法得到关联对象的实例。
//使用已得到的持久化对象通过关联关系调用其它对象时使用的检索策略,叫关联级别检索策略
PojoUser user = (PojoUser) session.load(PojoUser.class, 2);	//关联级别检索


2)类级别检索的延迟:

(1)类级别的检索配置:hbm文件中<class>的lazy属性,false:立即检索;true:延迟检索(默认)。

<class lazy="false">

(2)仅对load方法有效,因为get方法一定使用立即检索。

(3)类级别的Query查询使用立即检索。

结论:对于get或者Query类级别检索都是立即检索;通过hbm配置load使用立即或者延迟检索,默认延迟。

3)关联级别检索策略:

(1)关联级别的检索配置:hbm文件中<set>的lazy属性,false:立即检索;true:延迟检索(默认)。

<set lazy="false">

(2)第一部分:关联集合检索。包括one-to-many、many-to-many

检索策略由lazy和fetch共同决定。lazy决定关联对象的初始化时机,fetch决定查询语句的形式。

《1》fetch取值:join-迫切左外连接查询、select-多条简单SQL语句 、subselect-子查询

《2》lazy取值 : true 、false 、extra

如果fetch采用join-左外连接查询,就会忽略lazy立即将数据检索出来

1) fetch="join" lazy=随意 --------- 立即检索,即SQL语句形式的左外连接

<set name="orders" fetch="join">

2) fetch="select" lazy="false" ------ 多条语句立即检索

fetch="select" lazy="true" ------- 多条语句延迟检索

fetch="select" lazy="extra" ------ 极其懒惰,比延迟检索更加延迟

3) fetch="subselect" lazy="false" -- 子查询方式的立即检索

fetch="subselect" lazy="true" ---- 子查询方式的延迟检索

fetch="subselect" lazy="extra" --- 子查询方式的极其懒惰查询,比延迟检索更加延迟,只有访问到子实例的属性时,才会去查询。

4) lazy=true ------ 集合对象iterator()、size()、isEmpty()、contains()都会导致初始化

lazy=extra ----- 集合对象iteratoer()会导出初始化;size()、isEmpty()、contains()不会导致初始化

注意:当使用Query查询时,不会根据延迟策略生成hql语句,需要手动编写。Query查询会忽略fetch="join"配置,继而lazy生效

(3)第二部分:关联单个对象检索。包括many-to-one、one-to-one

由fetch和lazy两个属性决定检索策略。fetch决定SQL语句形式,lazy决定检索数据的时机

1) fetch="join" ------------------------ lazy被忽略,迫切左外连接查询(立即检索)

2) fetch="select" lazy="false" ------ 多条SQL立即检索

fetch="select" lazy="proxy" ----- 将由关联类级别检索策略决定是延迟还是立即

3.批量检索:

减少select语句个数,提高检索性能。

1)使用情景1:从客户访问订单:

在主表(一端)关联的<set>中设置batch-size属性,默认1。

Pojo.hbm.xml

<set batch-size="每次查询的客户数量">


2)使用情景2:从订单访问客户:

在从表(多端)所属的<class>配置batch-size。

Pojo.hbm.xml

<class batch-size="3">


4.结论:

1)开发中优先使用延迟检索。
2)业务要求立即检索,则不可延迟。
3)对于类级别检索,需要立刻使用数据对象,使用立即检索(优先左外连接)。
4)对于一对多、多对多关联,集合对象,使用延迟检索。

- end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息