本文实例讲述了Hibernate延迟加载原理与实现方法。分享给大家供大家参考,具体如下:
为了进一步优化Hibernate的性能,可以使用:
延迟加载技术、管理数据抓取策略、进行缓存管理 等方面考虑来提高Hibernate的性能。
1. 延迟加载(load)
延迟加载(load)是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
延迟加载的过程:通过代理(Proxy)机制来实现延迟加载。Hibernate从数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据(除标识符外),Hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只有在真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据。
当调用Session上的load()方法加载一个实体时;当Session加载某个实体时,会对这个实体中的集合属性值采用延迟加载;当Session加载某个实体时,会对这个实体所单端关联的另一个实体对象采用延迟加载
关闭延迟加载:在加载单个实体时,可以使用get()方法。
对于实体中的集合属性,可以在这个集合的(<set>,<bag>,<list>…)添加属性lazy="false"。单端关联另一个实体对象时,可以在映射文件中配置<one-to-one>,<many-to-one> 添加属性lazy="false"注意:one-to-one不能有constrained=true(产生的sql语句中显示外键),否则懒加载不起作用。
2. Hibernate中默认采用延迟加载的情况主要有以下几种:
• 当调用Session上的load()方法加载一个实体时会采用延迟加载。
• 当Session加载某个实体时,会对这个实体中的集合属性值采用延迟加载。(one-to-many)
• 当Session加载某个实体时,会对这个实体所单端关联(one-to-one, many-to-one)的另一个实体对象采用延迟加载。
• 第二种和第三种的区别是:第二种情况下取消延时加载的方法是在单方即有set属性的一方的映射文件的set标签后设置懒加载的属性lazy="false";第三种情况则是在多方即有many-to-one的一方的映射文件中的many-to-one标签后设置lazy="false"。
能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。
3. 抓取策略(fetch)
通过配置"抓取策略"来直接影响session的get()和load()方法的查询效果。
单端关联<many-to-one><one-to_one>上的抓取策略:
可以给单端关联的映射元素添加fetch属性。select:延迟加载; join:在同一条select语句使用内连接来获得对象的数据和它关联对象的数据,此时关联对象的延迟加载失效。
集合属性上的抓取策略:
select:延迟加载;join:在同一条select语句使用内连接来获得对方的关联集合。此时关联集合上的lazy会失效。subselect:另外发送一条查询语句或子查询抓取。这个策略对HQL的查询也起作用。
4. 延迟加载案例分析
情况一:单个实体调用load()方法取消懒加载
情况二:set集合上取消懒加载
测试如果在映射文件中将集合属性中的懒加载设置为false后将连带着orders表中数据一块提出来,即两条select语句
方法三:<one-to-one>,<many-to-one> 取消懒加载
希望本文所述对大家基于Hibernate框架的Java程序设计有所帮助。



















