web进修之—Hibernate 懒加载(6)
关于懒加载
在关系数据库设计的时候,我们很多时候把表之间的关系设置为强关联(使用外键进行约束),在Hibernate中利用对象的包含关系进行维护(HIbernate本身就是面向对象的数据库操作模式),例如class有很多student,我们在查询class的时候如果我们把class对应的student都查询出来,student很多的话效率是很低的,但是我们并不会用到class对应的student,这个时候我们希望不去查询student,只有在用到的时候再去查询。这就是Hibernate的懒加载存在的原因——不立即去查询数据库,先使用一个代理对象,在用到的时候再去查询数据库(如果对应的Session还open的话)。
在进行详细介绍之前,先理解一下代理:
代理:Hibernate动态生成的一个类,继承自需要代理的实体类,所以如果实体类要用到懒加载就不能声明为final的。
优点:
减少不必要的查询,提高与数据库交互的效率
缺点:
在使用懒加载后,如果我们需要把student返回前台,但是这个时候session已经关闭,Hibernate不能根据代理对象查询数据库,这个时候再使用student的时候会报LazyInitializationException。
懒加载的配置
lazy(指定抓取时机,什么时候去数据库查询)
用在<class>标签上(只是说明在使用load本类的时候的加载策略):
- true:默认的取值,使用懒加载
- false:不使用懒加载
用在<set>、<list>上
- true:默认取值,使用到该集合里面的元素时才查询
- false:不使用懒加载,直接查询
- extra:如果调用的是size/contains方法的时候不去查询,在真正使用里面的元素的时候才查询
用在<one-to-one>和<many-to-one>上
- false:不使用懒加载策略
- proxy:默认取值,在使用到的时候才进行查询
- no-proxy:(很少使用,需编译时期字节码增强)在使用到关联对象的属性(或者其get、set方法)的时候才会查询,使用关联对象的普通方法的时候不会查询,但是编译的时候需要字节码增强(就是在类进行编译的时候使用一定方式增加类的字节码,用来丰富字节码的内容,增强字节码以实现特定的功能,比如我们这儿生成可供hibernate 进行懒加载所需要的功能,编译时期增强字节码的方式有:JVM代理,第三方类加载器),例如
- class Person{
- private Card card = null;
- // setter& getter
- }
- class Card{
- private String number;
- // setter & getter
- public void upgrade(){
- // TODO
- }
- }
- class Test{
- public static void main(String[] args){
- Person p = (Person)session.get(Person.class, 1);
- // 会访问数据库
- p.getCard().getNumber();
- // 不会访问数据库
- p.getCard().upgrade();
- }
- }
class Person{
private Card card = null;
// setter& getter
}
class Card{
private String number;
// setter & getter
public void upgrade(){
// TODO
}
}
class Test{
public static void main(String[] args){
Person p = (Person)session.get(Person.class, 1);
// 会访问数据库
p.getCard().getNumber();
// 不会访问数据库
p.getCard().upgrade();
}
}
fetch(指定抓取方式,怎么查询数据)
- join:使用表连接的方式抓取,使用join的时候lazy配置失效
- select:查询的时候另外发送一条select语句
出现懒加载的情况
使用load单个对象,这个对象会被懒加载
比如session.get(student.class, 1),student会被懒加载,使用getId的时候不回去查询数据库,因为id是由Hibernate维护的
使用<one-to-one>
查询主对象,默认使用join进行连接查询,不使用懒加载,
查询从对象默认使用懒加载,先发送一条select查询从对象,在使用到的时候再发送一条select查询主对象
使用<many-to-one>
查询多的一方的时候使用懒加载(使用Hibernate的时候,而不是JPA)
使用<set>/<list>
默认使用懒加载
懒加载问题解决
在开始的时候我们说了懒加载出现的问题,下面给出三种懒加载的解决方案
方法一:使用Hibernate.initialize(object)
在session未关闭之前调用该方法初始化想要加载的对象,例如
Hibernate.initialize(student);
Hibernate.initialize(student.getCourses());
方法二:重新关联到session
当对象处于脱管的状态,使用lock方法重新关联到session,转化为持久态
- //直接重新关联
- session.lock(object, LockMode.NONE);
- //进行版本检查后关联
- session.lock(object, LockMode.READ);
- //使用SELECT ... FOR UPDATE进行版本检查后关联
- session.lock(object, LockMode.UPGRADE);
//直接重新关联
session.lock(object, LockMode.NONE);
//进行版本检查后关联
session.lock(object, LockMode.READ);
//使用SELECT ... FOR UPDATE进行版本检查后关联
session.lock(object, LockMode.UPGRADE);
方法三:使用OPenSessionInView
OpenSessionInViewFilter一个filter,这个filter把session绑定到当前请求线程上,只要在请求的生命周期内,就可以访问懒加载的对象。配置:
- <filter>
- <filter-name>hibernateOpenSessionInViewFilter</filter-name>
- <filter-class>org.springside.modules.orm.hibernate.OpenSessionInViewFilter</filter-class>
- <init-param>
- <param-name>flushMode</param-name>
- <param-value>AUTO</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>hibernateOpenSessionInViewFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
<filter>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<filter-class>org.springside.modules.orm.hibernate.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
参考:
http://www.cnblogs.com/linbaoji/archive/2009/01/07/1370919.html
http://blog.csdn.net/yaorongwang0521/article/details/7074573
特别感谢以上文章的作者,如若有冒犯或者侵权的地方,请及时联系本人修改。
web进修之—Hibernate 懒加载(6)的更多相关文章
- 关于s2sh框架关于hibernate懒加载问题的说明和解决方案
首先我们来看下面这个图,解释了一个web程序的一次请求流程! 懒加载异常的说明: 懒加载就是我们在查询一个对象时,它所有的属性是否要被查出来! 如果懒加载开启的话,session在service层就被 ...
- 关于Hibernate懒加载问题的最终解决方案
看到一篇Hibernate懒加载的文章,所以转载,原地址如下: http://tuoxie007.iteye.com/blog/334853 Hibernate的强大之处之一是懒加载功能,可以有效的降 ...
- 【转】hibernate懒加载的问题,failed to lazily initialize a collection of role
hibernate懒加载的问题,failed to lazily initialize a collection of role hibernate懒加载的问题,failed to lazily in ...
- Hibernate懒加载导致json数据对象传输异常的问题---(非常重要)
1. 异常: [console_demo][WARN] [2016-12-15 19:49:35] org.springframework.web.servlet.mvc.support.Defaul ...
- hibernate懒加载(转载)
http://blog.csdn.net/sanjy523892105/article/details/7071139 懒加载详解 懒加载为Hibernate中比较常用的特性之一,下面我们详细来了解下 ...
- Hibernate懒加载的三种解决方案
Hibernate懒加载的两种解决方案: 1.Hibernate.initialize(代理对象) 2.在*.hbm.xml映射文件中添加lazy="false"属性 3.使用op ...
- Hibernate懒加载解析
Hibernate懒加载解析 在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,这时Hibernate用懒加载机制来 ...
- hibernate懒加载
Hibernate懒加载解析 hibernatejoinsession数据库sqlobject Hibernate懒加载解析 在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适 ...
- Hibernate懒加载深入分析
Hibernate懒加载深入分析 懒加载可以提高性能吗? 不可以简单的说"能",因为Hibernate的关系映射拖累了SQL的性能,所以想出懒加载来弥补.只是弥补而以,不会超越. ...
随机推荐
- JSOI2018 简要题解
潜入行动 复杂度分析题. 定义状态fi,j,0/1,0/1f_{i,j,0/1,0/1}fi,j,0/1,0/1表示以iii为根子树放jjj个机器iii这个放不放,iii这个是否已放来进行dpdpd ...
- oracle 索引移动到不同的分区
最近系统空间不够,要进行数据库清理,truncate数据之后,发现数据不连续,导致这个表空间占用巨大,想过使用shrink.move.但是shrink得效率比较慢,选择了move.语句大概如此: SE ...
- python生成exe文件
安装pyinstaller pyinstaller支持python2和python3 命令行安装:pip install pyinstaller pyinstaller --icon=duoguan. ...
- POJ - 3278 Catch That Cow bfs 线性
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> usi ...
- The test form is only available for requests from the local machine
使用浏览器测试Web服务时出现提示“The test form is only available for requests from the local machine.”的解决办法 在Web服务项 ...
- Java 并发编程:核心理论
并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密,这样才能写出高效.安全.可靠的多线程并发程序.本系 ...
- Openvswitch手册(5): VLAN and Bonding
我们这一节来看Port 一般来说一个Port就是一个Interface,当然也有一个Port对应多个Interface的情况,成为Bond VLAN Configuration Port的一个重要的方 ...
- 【每日一点】1. Java如何实现导出Excel单表头或多表头
一.背景 在后台项目中,经常会遇到将呈现的内容导出到Excel的需求,通过都是导出单个表头的Excel文件,如果存在级联关系的情况下,也就需要导出多表头的场景.今天这篇文章就是分享导出Excel单表头 ...
- Senparc.Weixin.TenPay 正式发布
微信支付刚出来的时候,和公众号的绑定关系很深(甚至旧版本使用的就是公众号的appId),随着微信生态的逐步丰富,微信支付越来越成为一个独立的平台,同时服务于公众号.小程序.开放平台.企业号/企业微信等 ...
- Java中最常用的集合类框架之 HashMap
一.HashMap的概述 HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构. HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射 ...