Hibernate学习笔记 | Hibernate检索策略

类级别的检索策略

类级别可选的检索策略包括立即检索和延迟检索,默认为延迟检索

  • 立即检索:立即加载检索方法指定的对象
  • 延迟检索:延迟加载检索方法指定的对象,在使用具体的属性时,再进行加载

类级别的检索策略可以通过<class>元素的lazy属性进行设置

  • lazytrue时,就是延迟检索。
  • lazyfalse时,就是立即检索。

如果程序加载一个对象的目的是为了访问它的属性,可以采取立即检索。如果程序加载一个持久化对象的目的是仅仅为了获得它的引用,可以采取延迟检索,在使用延迟检索时,要防止懒加载异常。

无论<class>的元素的lazy属性是true还是false,Session的get()及Query的list()在类级别总是使用立即检索策略。

<class>元素的lazy属性为true或取默认值,Session的load()不会执行查询数据表的SELECT语句,仅返回代理类对象的实例,该代理类实例有如下特征:

  • 由Hibernate在运行时采用CGLIB工具动态生成
  • Hibernate创建代理类实例时,仅初始化其OID属性
  • 在应用程序第一次访问代理类实例的非OID属性时,Hibernate会初始化代理类实例。

延迟检索和增强延迟检索

在延迟检索(lazy属性为true)集合属性时,Hibernate在以下情况下初始化集合代理类实例

  • 应用程序第一次访问集合属性:iterator(),size(),isEmpty(),contains()等方法
  • 通过Hibernate.initialize()静态方法显示初始化

增强延迟检索(lazy属性为extra)时,与延迟检索类似,主要区别是增强延迟检索策略能进一步延迟实体类对象的集合代理实例的初始化时机

  • 当程序第一次访问集合属性的iterator()时,会导致集合代理类实例的初始化
  • 当程序第一次访问集合属性的size(),contains(),isEmpty()时,Hibernate不会初始化集合类的实例,仅通过特定的SELECT语句查询必要的信息,不会检索所有的集合对象。

一对多和多对多的检索策略

在映射文件中,用<set>元素来配置一对多关联及多对多关联关系,<set>元素有lazyfetch属性。

  • lazy:主要决定实体类中关联的集合被初始化的时机。即到底是在加载实体类对象的时候就被初始化呢,还是在程序访问集合时被初始化。
    默认为true,即访问集合时被初始化,可以设置为false,即加载实体类对象的时候就初始化。lazy还可以设置为extra,是一个增强版的延迟检索,会尽可能地延迟集合初始化的时机。

  • <set>元素的batch-size属性
    用来为延迟检索策略或立即检索策略设定批量检索的数量。批量检索能减少SELECT语句的数目,提高延迟检索或立即检索的运行性能。
    配置示例:

<!-- 一次性检索5个集合-->
<set name="orders" table="orders" inverse="true" cascade="delete" batch-size="5">
       <key column="customer_id"></key>
       <one-to-many class="Order"/>
</set>
  • fetch:决定初始化集合的方式。
    取值为selectsubselect时,决定初始化集合的查询语句的方式,subselect是子查询,此时batch-size属性将被忽略;若取值为join,则决定集合被初始化的时机。在加载一端的实体类对象时,使用迫切左外连接(使用左外连接进行查询,且把集合属性进行初始化)的方式检索n端的集合属性若把fetch设置为join的话,lazy属性将被忽略。若使用HQL查询,则忽略fetch=join

多对一和一对一关联的检索策略

set一样,<many-to-one>元素也有一个lazy属性和fetch属性

lazy属性(默认值为proxy) fetch属性(默认值为select) 检索实体对象时对关联的实体对象使用的检索策略
proxy 未显式设置(默认值为select) 采取延迟检索
no-proxy 未显式设置(默认值为select) 无代理延迟检索
false 未显式设置(默认值为select) 立即检索
未显式设置(默认值为proxy) join 迫切左外连接策略
  • fetch属性设为join,那么lazy属性被忽略,并且使用迫切左外连接来初始化n端关联的1端的属性

  • 迫切左外连接检索策略的优点在于比立即检索策略使用的SELECT更少

  • 无代理延迟检索需要增强持久化类的字节码才能实现

  • Querylist()会忽略映射文件配置的迫切左外连接检索策略,而采用延迟检索策略

  • batch-size:一次性初始化1端的代理对象的个数。该属性需要设置在1端的class元素中
    示例:<class name="Customer" table="customers" batch-size="5">

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章