在默认情况下,当Hibernate从数据库中加载对象时,会同时加载所有关联的对象. 但实际应用中可能不需要使用其关联的对象,这样就可能通过设置Hibernate的检索策略,来优化检索性能.
Hiberante提供了3种检索策略:1)立即检索 2)延迟检索 3)迫切左外连接检索
下面先从概念上去理解,先在脑袋中有个印象,看到了这样的用法知道是怎么回事,它在做什么.为什么这样做.
真正的理解要在以后的项目经验中慢慢去体会,
下表列出了类级别和关联级别可选的检索策略,以及默认的检索策略.
检索策略的作用域 | 可选的检索策略 | 默认的检索策略 | 运行时受影响的Session的检索方法 |
类级别 | 立即检索 延迟检索 | 立即检索 | 仅影响load()方法 |
关联级别 | 立即检索 延迟检索 | 多对一和一对一关联为外连接检索 | 影响load(),get()和find()方法 |
迫切左外连接检索 | 一对多和多对多关联为立即检索 |
下表列出了 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>元素中包含此属性 |
下表比较Hiberante的三种检索策略
检索策略 | 优点 | 缺点 | 优先考虑使用的场合 |
立即检索 | 对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地从一个对象导航到与它关联的对象 | (1)select 语句数目多 (2)可能会加载应用程序不需要访问的对象,白白浪费许多内存空间 | (1)类级别 (2)应用程序需要立即访问的对象 (3)使用了第二级缓存 |
延迟检索 | 由应用程序决定需要加载那些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象.因此能提高检索性能,并且能节省内存空间 | 应用程序如果希望访问游离状态的代理类实例,必须保证它在持久化状态已经被初始化 | (1)一对多或者多对多关联 |
迫切左外连接检索 | (1)对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地从一个对象导航到与它关联的对象 (2)使用了外连接,select语句数目少 | (1)可能会加载应用程序不需要访问的对象,白白浪费许多内存空间 (2)复杂的数据库表连接也会影响检索性能 | (1)多对一或者一对一关联 (2)应用程序需要立即访问的对象 (3)数据库系统具有良好的表连接性能 |