近段时间在读孙维琴的《精通hibernate》,感觉收获不少,对于hibernate检索策略的第一部分,感觉其实就是几张表,如果把几张表搞清楚了,其他的也就无所谓了,幸而书中总结的很好,就摘录如下:
注意:此版本主要是基于hibernate2.x版本。
类级别和关联级别可选的检索策略和默认的检索策略
检索策略的作用域 |
可选的检索策略 |
默认的检索策略 |
运行时行为受影响的sesssion的检索方法 |
类级别 |
立即检索
延迟检索 |
立即检索 |
仅影响load()方法 |
关联级别 |
立即检索
延迟检索
迫切左外连接检索 |
多对一和一对一关联为外连接检索 |
影响load(),get(),find()方法 |
一对多和多对多关联为立即检索 |
三种检索策略的运行机制
检索策略的类型 |
类级别 |
关联级别 |
优点 |
缺点 |
优先考虑使用的场合 |
立即检索 |
立即加载检索方法指定的对象 |
立即加载与检索方法指定的对象关联的对象,可以设定批量检索数量 |
对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地从一个对象导航到与它关联的对象 |
(1)select语句数目多;(2)可能会加载应用程序不需要访问的对象,造成内存空间的浪费 |
(1)类级别(2)应用程序需要立即访问的对象(3)使用了二级缓存 |
延迟检索 |
延迟加载检索方法指定的对象 |
延迟加载与检索方法指定的对象,可以设定批量检索数量 |
由应用程序决定需要加载那些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此提高检索性能,并能节省内存空间 |
应用程序如果希望访问游离状态的代理类实例,必须保证它在持久化状态时已经被初始化 |
(1)一对多或多对多关联(2)应用程序不需要立即访问或者根本不会访问的对象 |
迫切左外连接检索 |
不适用 |
通过左外连接加载与检索方法指定的对象 |
(1)对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地从一个对象导航到与它关联的对象(2)使用了外连接,select语句数目少 |
(1)可能会加载应用程序不需要访问的对象,造成内存空间的浪费(2)复杂的数据表连接也会影响检索性能 |
(1)多对一或一对一关联(2)应用程序需要立即访问的对象(3)数据库系统具有良好的表连接性能 |
映射文件中用于设定检索策略的几个属性
属性 |
可选值 |
默认值 |
描述 |
lazy |
true或false |
hibernate2.x版本为false
hibernate3.x版本为true |
如果为true,表示使用延迟策略。在<class>和<set>中包含此属性 |
outer-join |
auto、true或false |
在<many-to-one>和<one-to-one>元素中为auto;在<set>元素中为false |
如果为true,表示使用迫切左外连接检索。在<many-to-one>、<one-to-one>和<set>元素中包含此属性 |
batch-size |
正整数 |
1 |
设定批量检索的数量。如果设定此项,合理的取值在3~10之间。仅适用于关联级别的立即检索和延迟检索,在<class>和<set>元素中包含此属性 |
Set元素的lazy和outer-join属性
lazy属性 |
outer-join属性 |
检索策略 |
false |
true |
采用立即检索,这是默认的检索策略,当使用hibernate二级缓存可以考虑使用立即检索 |
false |
false |
采用迫切左外连接检索。对于hibernate2.x版本,在映射文件中如果有多个<set>元素,只允许有一个<set>元素的outer-join属性为true |
true |
false |
采用延迟检索。这是优先考虑的检索策略 |
true |
true |
没有任何意义 |
设置多对一关联的检索策略
(以客户和订单为例)
Order.hbm.xml的<many-to-one>元素的outer-join属性 |
Customer.hbm.xml的<calss>元素的lazy属性 |
检索order对象时,对关联的customer对象使用的检索策略 |
auto |
true |
延迟检索 |
auto |
false |
迫切左外连接检索 |
true |
true |
迫切左外连接检索 |
true |
false |
迫切左外连接检索 |
false |
true |
延迟检索 |
false |
false |
立即检索 |
注:
1默认情况下,Hibernate 3对集合使用延迟select抓取,对返回单值的关联使用延迟代理抓取。
2在Hibernate2.1中,lazy属性的默认值为“false”,而在Hibernate3.0中,lazy属性的默认值为“true”。
3FetchMode.LAZY 和 FetchMode.EAGER被废弃。取而代之的分别为FetchMode.SELECT 和FetchMode.JOIN。