Hibernate<六> Hibernate的检索策略

一、Hibernate检索策略

1、Hibernate提供了三种检索策略:立即检索策略、延迟检索策略(懒加载机制)、迫切左外连接检索策略。Hibernate在3.x以前lazy属性默认为false,Session的get()方法、load()方法默认都使用的是立即检索策略。从3.x以后,lazy属性为true,get()方法使用的是立即检索策略,load()方法默认使用的延迟检索策略。

以前默认的立即检索策略存在两大不足:

①、select语句的数据太多,需要频繁的访问数据库,会影响检索性能。如果需要检索查询n个Customer对象,那么必须执行n+1次select查询语句。这种检索策略没有利用sql的链接查询功能,例如,以上5条select语句完全可以通过以下一条select语句完成:select * from customer left outer join Orders on customers.id=orders.customer_id

②、在应用逻辑只需要访问Customer对象,而不需要访问Order对象的场合,加载Order对象完全是多余的操作,这些多余的Order对象白白浪费了许多内存空间。

而HIbernate提供的延迟检索策略能避免多余加载应用程序不需要访问的关联对象,迫切左外连接检索策略则充分利用了sql的外连接查询功能,能够减少select语句的数目。

2、类级别和关联级别的检索策略

检索策略的作用域 可选的检索策略 默认的检索策略 运行时行为受影响的Session的检索方法

类级别


立即检索

延迟检索

立即检索 仅影响load()方法
关联级别
立即检索

延迟检索

迫切左外连接检索


多对一和一对一关联为外连接检索

一对多和多对多关联为立即检索

影响Load()、get()和find()方法

在类级别中,可选的检索策略包括立即检索和延迟检索策略,但是它仅影响load()方法,在关联级别中,可选的检索策略包括立即检索、延迟检索和迫切左外连接检索。

三种检索策略的运行机制:

检索策略类型 类级别 关联级别
立即检索 立即加载检索方法指定的对象
立即加载与检索方法指定的对象关联的对象。

延迟检索 延迟加载检索方法指定的对象 延迟加载与检索方法指定的对象关联的对象。
迫切左外连接检索 不适用 通过左外连接加载与检索方法指定的对象关联的对象

二、类级别的检索策略:

1、类级别可选的检索策略包括立即检索和延迟检索,默认为立即检索。如果<class>元素的lazy属性为true,表示采用延迟检索。如果lazy属性为false,表示采用立即检索。从Hibernate3.x以后,类级别的lazy默认为true,表示load()方法采用延迟检索策略。当执行Session的load()方法时,Hibernate不会立即执行查询CUSTOMER表的select语句,仅仅返回Customer类的代理类的实例,这个代理类有以下特征:

①、由Hibernate在运行时动态生成,它扩展了Customer类,因此它继承了Customer类的所有属性和方法,但它的实现对于应用程序时透明的。

②、当HIbernate创建Customer代理类实例时,仅仅初始化了它的OID属性,其他属性全为null,因此这个代理类实例占用内存很少。

③、当应用程序第一次访问Customer代理类实例时,例如调用Customer.getName()方法,HIbernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库加载 Customer对象的所有数据。但有个例外,那就是当应用程序访问Customer代理类实例的getId()方法,HIbernate不会初始化代理类实例。

Hibernate类的initialize()静态方法用于在Session范围内显式初始化代理类实例,isInitialize()方法用于判断代理类实例是否已经被初始化。

三、一对多和多对多检索策略

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

lazy属性 outer-join属性 检索策略
false false 采用立即检索,这是默认的检索策略
false true 采用迫切左外连接检索策略
true false 采用延迟检索策略
true true 毫无意义

HIbernate为Set集合也提供了代理类,它扩展了Set接口,但它的实现对应用程序时透明大的。

<set>元素有一个batch-size属性,用于为延迟检索或立即检索策略设定批量检索数量。批量检索能够减少select语句,提高延迟检索检索或立即检索的性能。

当<set .....batch-size=3>时,HIbernate的select语句,会变为:select * from orders where customer_id=1 or customer_id=2 or customer_id=3。必须根据实际情况确定批量检索数目,合理的批量检索数目应该控制在3到10之间。

outer-join=true属性,设置迫切左外连接检索策略。

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

1、<many-to-one>元素有一个outer-join属性,他有三个可选值:

①、auto:这是默认值,如果Customer.hbm.xml文件的class元素的lazy属性为true,那么对于Order关联的Customer对象采用延迟检索策略。否则采用迫切左外连接检索策略。

②、true。不管Customer.hbm.xml文件的class元素的lazy属性为true还是false,对于Order关联的Customer对象都采用迫切左外连接检索策略。

③、false:始终不会对于ORder关联的Customer对象采用迫切左外连接检索策略。

对于多对一或一对一关联,应该优先考虑使用外连接检索策略,因为它比立即检索策略使用的select数据少,假如应用程序仅仅希望访问ORder对象,并不需要立即访问与ORder对象关联的Customer对象,也可以考虑使用延迟检索策略。

在<one-to-one>一对一关联中,如果使用懒加载机制,必须把<one-to-one>元素中的constrained属性设为true,(constrained属性只能用在一对一关联中)。

五、Hibernate对迫切左外连接检索的限制

假如select语句包含多个一对多关联的外连接,会导致一次检索出大批量的数据,从而影响检索性能,因此Hibernate对迫切左外连接做了限制:

①、在一个select语句中只允许包含一个一对多或多对多关联的迫切左外连接。

②、在一个select语句中允许包含多个多对一或一对一关联的迫切左外连接。

时间: 2024-11-06 02:23:48

Hibernate<六> Hibernate的检索策略的相关文章

Hibernate 检索策略

概述 检索数据时的 2 个问题: –不浪费内存:当 Hibernate 从数据库中加载 Customer 对象时, 如果同时加载所有关联的 Order 对象, 而程序实际上仅仅需要访问 Customer 对象, 那么这些关联的 Order 对象就白白浪费了许多内存. –更高的查询效率:发送尽可能少的 SQL 语句 类级别的检索策略 •类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索 –立即检索: 立即加载检索方法指定的对象 –延迟检索: 延迟加载检索方法指定的对象.在使用具体的属性时

[原创]java WEB学习笔记88:Hibernate学习之路-- -Hibernate检索策略(立即检索,延迟检索,迫切左外连接检索)

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Hibernate复习(六)检索策略

1.立即检索策略 默认的检索策略. 缺点: select语句的数目太多,需要频繁的访问数据库,会影响检索性能.如果需要查询n个Customer对象,那么必须执行n+1次select查询语句. 这种检索策略没有利用SQL的连接查询功能.利用left join 只需一条sql语句既可以实现N+1次查询的结果.并且可能造成内存空间的浪费. 2.延迟策略 在一对多关联级别中对于<set>元素,应该优先考虑使用延迟检索策略. ? 优点 – 由应用程序决定需要加载哪些对象,可以避免执行多余的select语

Hibernate —— 检索策略

一.Hibernate 的检索策略本质上是为了优化 Hibernate 性能. 二.Hibernate 检索策略包括类级别的检索策略.和关联级别的检索策略(<set> 元素) 三.类级别的检索策略 1. 立即检索.延迟检索 2. 通过 <class> 节点的 lazy 属性来控制.默认为 true,即为延迟检索. 3. 只针对 session 的 load() 方法生效. 默认情况下,通过 load() 方法获取到的对象是一个代理对象,Hibernate 创建代理对象时,仅会初始化

Hibernate的检索策略

hibernate 的中的session依照load()和get()按照参数的制定OID(ObjctID)去加载一个持久化对象.另外Query.list()方法则按照HQL语句去加载持久化的对象. 以上的几个方式都可以实现hibernate的持久化对象的加载.如果有不懂hibernate对象的"临时状态"."游离态"."持久态"."删除状态"的小伙伴,自己先去了解下. 对于hibernate的以上的几种检索策略,我们先来了解下

hibernate(八) Hibernate检索策略(类级别,关联级别,批量检索)详解

序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要想想,你花费的也就那么一点时间,别人花你这么多时间也能够学到你所学到的东西,所以还是要继续努力.既然不是天才,唯有靠勤奋来弥补. --WH 一.概述 检索策略分三大块,类级别检索策略和关联级别检测策略. 类级别检索策略:get.load. 关联级别检索策略:order.getCustomer().g

Hibernate学习之检索策略

一.类级别的检索策略 类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索 –立即检索: 立即加载检索方法指定的对象 –延迟检索: 延迟加载检索方法指定的对象,在使用具体的属性时,再进行加载 类级别的检索策略可以通过 <class> 元素的 lazy 属性进行设置,如果程序加载一个对象的目的是为了访问它的属性, 可以采取立即检索:如果程序加载一个持久化对象的目的是仅仅为了获得它的引用, 可以采用延迟检索.注意出现懒加载异常! –无论 <class> 元素的 lazy 属性是

Hibernate检索策略之延迟加载和立即加载

延迟加载:延迟加载(lazy load懒加载)是当在真正需要数据时,才执行SQL语句进行查询.避免了无谓的性能开销. 延迟加载分类:  1.类级别的查询策略 2.一对多和多对多关联的查询策略 3.多对一关联的查询策略 什么情况下使用延迟加载? 如果程序加载一个对象的目的是为了访问它的属性,可以采用立即加载.如果程序加载一个持久化对象的目的是仅仅为了获得它的引用,可以采用延迟加载. 如何配置延时加载? 在Hibernate中通过对.hbm的lazy属性来赋值,不同位置出现lazy的作用和取值也是不

Hibernate检索策略

Hibernate的检索策略主要分为两类: 1. 立即查询:根据id查询,调用get方法,调用get方法马上发送语句查询数据库 2. 延迟查询:根据id查询,还有load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值的时候才会发送语句查询数据库. Hibernate的延迟查询又分为两类: 1. 类级别延迟:根据id查询返回实体类对象,调用load方法不会马上发送语句 2. 关联级别延迟:查询某个客户,在查询这个客户的所有联系人,查询客户的所有联系人的过程是否需要延迟,这个过