Hibernate有三种检索策略:立即检索策略、延迟检索策略和迫切左外连接检索策略。
1.类级别的检索策略:
在类级别中应该优先考虑立即检索策略,因为在大多数情况下,当应用程序通过session的load()的方法加载一个持久化对象后,总会立即访问它。
当使用延迟检索策略,执行session的load()方法时,仅仅返回类的代理类的实例,当程序第一次访问代理类时,Hibernate会初始化代理类实例,真正从数据库中加载类的对象的所有数据。
注意不管class的lazy属性是true还是false,Session的get()和find()方法在类级别总是使用立即检索策略。
2.关联级别的检索策略:
session的find()方法会忽略映射文件中配置的迫切左外连接检索策略。
batch-size:批量检索的大小。
hibernate.max_fetch_size属性用来控制外连接的深度。
Hibernate 2.x版本对迫切左外连接的限制
在一个select语句中只允许包含一个 一对多关联 或 多对多关联的迫切左外连接
在一个select语句中允许包含多个 一对一关联 或 多对一关联的迫切左外连接
设置Hibernate的检索策略,优化检索性能。
一、Hibernate的检索策略简介
Session有3种检索方式:load()、get()和find(),它们都用来从数据库中检索对象。前两个是按照参数指定的OID来加载一个持久化对象,后者安周参数指定的HQL语句来加载一个或者多个持久化对象。
当Hibernate执行以上方法时,需要获得以下信息:
l 类级别检索策略:分立即检索和延迟检索2种策略。
l 关联级别检索策略:分立即检索、延迟检索和迫切左外连接检索3种策略。
类级别和关联级别可选的检索策略及默认的检索策略
检索策略的作用域 | 可选的检索策略 | 默认的检索策略 | 运行时行为收影响的Session的检索方法 |
类级别 | 立即检索 延迟检索 | 立即检索 | 仅影响load方法 |
关联级别 | 立即检索 延迟检索 迫切左外连接检索 | 多对一和一对一关联位外连接检索 | 3个方法都影响 |
一对多和多对多关联为立即检索 |
3种检索策略的运行机制
类型 | 类级别 | 关联级别 |
立即检索 | 立即加载检索方法指定的对象 | 立即加载与检索方法指定的随想关联的对象。可以设定批量检索数量 |
延迟检索 | 延迟加载检索方法指定的对象 | 延迟加载与检索方法指定的随想关联的对象。可以设定批量检索数量 |
迫切左外连接检索 | 不适用 | 通过左外连接加载与检索方法指定的随想关联的对象 |
映射文件中用于设定检索策略的几个属性
属性 | 可选值 | 默认值 | 描述 |
lazy | true或false | false | 如果为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 | false | 采用立即检索,这是默认的检索策略,当使用Hibernate的二级缓存时,可以考虑使用立即检索。 |
false | true | 采用迫切左外连接检索。 |
true | false | 采用延迟检索。这是优先考虑使用的检索策略。 |
true | true | 没有任何意义。 |
<set>元素有一个batch-size属性,用于为延迟检索或立即检索策略设定批量检索的数量。批量检索能减少select语句的数目,提高延迟检索或立即检索的性能。
Session的find方法会忽略映射文件配置的迫切左外练剑检索策略。
多对一和一对一关联
设置多对一关联的检测策略
<many-to-one>元素的 outer-join属性 | One对应类配置文件的<class>属性的lazy属性 | 检索many对象时对关联的one对象使用的检索策略 |
auto | True | 延迟检索 |
auto | False | 迫切左外连接检索(默认) |
true | true | 迫切左外连接检索 |
true | false | 迫切左外连接检索 |
false | true | 延迟检索 |
false | false | 立即检索 |
检索
延迟检索 | <class>属性的lazy属性设置为true; <many-to-one>元素的 outer-join属性可以设置为auto或者false。 |
立即检索 | <many-to-one>元素的 outer-join属性设置为false; <class>属性的lazy属性设置为false。 |
批量延迟检索 | |
批量立即检索 | |
迫切左外连接检索 |
比较三种检索策略
检索策略 | 优点 | 缺点 | 优先考虑使用的场合 |
立即检索 | 对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地从一个对象导航到与它关联的对象 | 1、select语句数目多 2、可能会加载应用程序不需要访问的对象,白白浪费许多内存空间 | 1.类级别 2.应用程序需要立即访问的对象 3.使用了第二级缓存 |
延迟检索 | 由应用程序决定需要加载那些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并且能节省内存空间 | 应用程序如果需要访问游离状态的代理类实例,必须保证它在持久化中太是已经被初始化 | 1.一对多或者多对多关联 2.应用程序不需要立即访问或者根本不会访问的对象 |
迫切左外连接检索 | 1、对应用程序完全透明,不管对象处于持久化状态还是游离状态,应用程序都可以方便的从一个对象导航到与他关联的对象 2、 使用了外连接,select语句数目减少 | 1、可能会加载应用程序不需要访问的对象,白浪费许多内存空间 2、 复杂的数据库表连接也会影响检索性能 | 1.多对一或者一对一关联 2.应用程序需要立即访问的对象 3.数据库系统具有良好的表连接性能 |