2019独角兽企业重金招聘Python工程师标准>>>

一.延迟加载的概念

当Hibernate从数据库中加载某个对象时,不加载关联的对象,而只是生成了代理对象,获取使用session中的load的方法(在没有改变lazy属性为false的情况下)获取到的也是代理对象,所以在上面这几种场景下就是延迟加载。

二.理解立即加载的概念

当Hibernate从数据库中加载某个对象时,加载关联的对象,生成的实际对象,获取使用session中的get的方法获取到的是实际对象。

三.为什么要使用延迟加载

延迟加载策略能避免加载应用程序不需要访问的关联对象,以提高应用程序的性能。

四.立即加载的缺点

Hibernate在查询某个对象时,立即查询与之关联的对象,我们可以看出这种加载策略存在两大不足:

1.select的语句数目太多,需要频繁的访问数据库,会影响查询的性能。

2.在应用程序只需要访问要的对象,而不需要访问与他关联的对象的场景下,加载与之关联的对象完全是多余的操作,这些多余的操作是会占内存,这就造成了内存空间的浪费。

五.什么时候使用延迟加载什么时候使用立即加载

如果程序加载一个持久化对象的目的是为访问他的属性,则可以采用立即加载。如果程序加载一个持久化对象的目的仅仅是为了获得他的引用,则可以采用延迟加载。

六.Hibernate在对象-关系映射问价中配置加载策略

I.类级别:

<class>元素中lazy属性的可选值为true(延迟加载)和false(立即加载);

<class>元素中的lazy属性的默认值为true

II.一对多关联级别:

<set>元素中的lazy属性的可选值为:true(延迟加载),extra(增强延迟加载)和false(立即加载);

<set>元素中的lazy属性的默认值为true

III.多对一关联级别:

<many-to-one>元素中lazy属性的可选值为:proxy(延迟加载),no-proxy(无代理延迟加载)和false(立即加载)

<many-to-one>元素中的lazy属性的默认值为proxy

在下面的一些案例中都会以员工(Emp)的部门(Dept)的例子讲解:

员工和部门是多对一的关系:

关于员工和部门的Hibernate配置就不啰嗦了:可以看我的这篇博客:http://www.cnblogs.com/heyongjun1997/p/5767187.html

I.1类级别的查询策略:

01.立即加载案例:

需求:通过Session的load()方法加载Dept对象时:

首先在Dept.hbm.xml文件中配置lazy属性为false,表示立即加载。

@Testpublic void loadDept() {// 获取Session对象Session session = HibernateUtil.currentSession();// 如果通过load方式加载Dept对象Dept dept=(Dept)session.load(Dept.class, 12);// 关闭sessionHibernateUtil.closeSession();}

我们知道使用Load方法加载的是代理对象,只会在属性里保存一个OID,但是如果在Dept映射文件中配置了类级别的lazy为false就代表加载该对象时立即加载,也就是立即检索一道数据库,发出sql:

02.延迟加载案例:

同样是获取Dept对象,但是要把Dept.hbm.xml配置文件的类级别的lazy属性改为lazy=”true” 或者不写,应为类级别的lazy属性默认就是true,

@Testpublic void loadDept() {// 获取Session对象Session session = HibernateUtil.currentSession();// 如果通过load方式加载Dept对象session.load(Dept.class, 12);// 关闭sessionHibernateUtil.closeSession();}

此时Dept.hbm.xml配置文件的类级别的lazy属性为true,则是延迟加载,那么load方法获取的知识Dept的代理对象,所以他不会去检索数据库。

II.1一对多和多对多关联的查询策略

01.立即加载案例:

在获取部门对象的时候同时获取员工对象:

设置Dept.hbm.xml 类级别的lazy属性为false;表示立即加载:

设置<set>元素的lazy属性为false,表示在加载部门的同时立即加载员工:

@Testpublic void loadDept() {// 获取Session对象Session session = HibernateUtil.currentSession();// 如果通过load方式加载Dept对象Dept dept=(Dept)session.load(Dept.class, 12);// 关闭sessionHibernateUtil.closeSession();}

控制台输出结果:

当你想获取一的一方(Dept)的对象同时,你也要加载多的一方(Emp)的对象,那么你要在一的一方(Emp)的<set>的节点上加上lazy="false"表示立即加载,所以在使用Load方式加载Dept对象的时候,Emp对象也会不加载出来,所以程序在运行到Dept dept=(Dept)session.load(Dept.class, 12);会发出两条sql语句:

第一条是查询部门的信息,第二条sql是根据部门编号去数据库中检索员工信息。

02.延迟加载:

如果把上面的案例<set>节点的属性lazy改为trur,或者默认不写,那么在加载Dept对象的时候,就不会再去加载Emp对象,而且只会发出一条sql,这条sql就是指检索部门的信息。

03.增强延迟加载:

当<set>元素中配置lazy的属性为extra,表明是增强延迟加载策略。

其实增强延迟加载策略与一般的延迟加载策略lazy="true"非常相似。他们主要区别在于,我们看到这个名词增强延迟加载,顾名思义就是这个策略能在进一步的帮我延迟加载这个对象,也就是代理对象的初始化时机。

演示案例:

01. 当set节点的lazy属性为true,或者不写的话(取默认值),那么执行以下语句:

@Testpublic void loadDept() {// 获取Session对象Session session = HibernateUtil.currentSession();// 如果通过load方式加载Dept对象Dept dept=(Dept)session.load(Dept.class, 12);//拿该部门下的员工的人数:也就是集合的大小dept.getEmps().size();// 关闭sessionHibernateUtil.closeSession();}

输出结果:

02. 当set节点的lazy属性为extra那么执行以下语句:

@Testpublic void loadDept() {// 获取Session对象Session session = HibernateUtil.currentSession();// 如果通过load方式加载Dept对象Dept dept=(Dept)session.load(Dept.class, 12);//拿该部门下的员工的人数:也就是集合的大小dept.getEmps().size();// 关闭sessionHibernateUtil.closeSession();}

输出结果:

III.1多对一关联的查询策略

在映射文件中,<many-to-one>元素用来设置多对一的关系,在Emp.hbm.xml文件中表明Emp类到Dept类的多对一的关联关系:

01.延迟加载

需求:获取Emp对象,但是并不去加载与之关联的Dept对象。

首先要设置<many-to-one>节点的lazy属性为proxy,表示延迟加载。

@Test
public void loadEmp() {
// 获取Session对象
Session session = HibernateUtil.currentSession();
// 如果通过load方式加载Dept对象
Emp emp=(Emp)session.get(Emp.class, 1);

//获取Dept对象,因为此时的配置文件lazy是proxy,所以是代理对象
Dept dept=emp.getDept();
// 关闭session
HibernateUtil.closeSession();
}

控制台输出结果:

结果大家可想而知:<many-to-one>节点的lazy属性为proxy,表示延迟加载。在加载Emp对象的时候会发出sql去查询数据库,但是在获取Dept对象的时候延迟加载了,所以不会发出sql。

02.无代理延迟加载:

在<many-to-one>元素中配置lazy属性为no-proxy,表示无代理延迟加载。

@Test
public void loadEmp() {
// 获取Session对象
Session session = HibernateUtil.currentSession();
// 如果通过load方式加载Dept对象
Emp emp=(Emp)session.get(Emp.class, 1);//获取Dept对象,因为此时的配置文件lazy是proxy,所以是代理对象
Dept dept=emp.getDept();
// 关闭session
HibernateUtil.closeSession();
}

此程序在加载的Emp对象dept属性为NULL,当程序运行到第3行的时候将触发Hibernate执行查询Dept表的select语句,,从而加载Dept对象,由此可见,当lazy属性为proxy时,可以延长延迟加载Dept代理对象的时间,而lazy属性为no-proxy时,则可以避免使用由Hibernate提供的Dept代理类实例,是Hibernate对程序提供更加透明的持久化服务。

03.立即加载:

首先要设置<many-to-one>节点的lazy属性为false,表示立即加载。

@Test
public void loadEmp() {
// 获取Session对象
Session session = HibernateUtil.currentSession();
// 如果通过load方式加载Dept对象
Emp emp=(Emp)session.get(Emp.class, 1);

//获取Dept对象,因为此时的配置文件lazy是false,所以是实际对象
Dept dept=emp.getDept();
// 关闭session
HibernateUtil.closeSession();
}

控制台输出结果:

转载于:https://my.oschina.net/u/3346994/blog/894514

Hibernate之lazy延迟加载相关推荐

  1. Hibernate 中lazy的作用

    Hibernate 中lazy的作用 上一篇 / 下一篇  2009-06-24 20:02:20 / 个人分类:java 查看( 506 ) / 评论( 2 ) / 评分( 5 / 0 ) < ...

  2. hibernate的lazy的使用

    引用:https://blog.csdn.net/Vincent_yuan1991/article/details/53482487 一: lazy,延迟加载 Lazy的有效期:只有在session打 ...

  3. hibernate中lazy的使用

    lazy,延迟加载 Lazy的有效期:只有在session打开的时候才有效:session关闭后lazy就没效了. lazy策略可以用在: * <class>标签上:可以取值true/fa ...

  4. (十六)Hibernate中的延迟加载

    一.什么是延迟加载 为了节省Hibernate加载对象的性能节销,在Hibernate中真正需要用到这个对象时,才会发出          SQL语句来抓取这个对象.这一个过程称为延迟加载. 二.延迟 ...

  5. java bean lazy proxy_java – Hibernate @Proxy(lazy = false)注释做什么...

    在尝试序列化作为JPA实体的ESRBRating对象时,我遇到了两个不同的堆栈跟踪(见下文).我正在使用Spring Data JPA.控制器调用服务,称为存储库的服务.我能够通过在我的ESRBRat ...

  6. hibernate lazy加载

    2019独角兽企业重金招聘Python工程师标准>>> HIBERNATE的持久化对象加载策略. 延迟加载, 也就是用到的时候才去加载.这样可以提高一些性能. Hibernate的l ...

  7. hibernate中load和get方法的区别 lazy的策略

    1  get不支持lazy   load支持lazy 2  采用get加载数据时,如果无匹配数据则返回null         load则报异常 --------------------------- ...

  8. hibernate 延迟加载问题探讨

    延迟初始化错误是运用Hibernate开发项目时最常见的错误.如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它.如果在 ...

  9. hibernate 延迟加载(转载)

    http://blog.csdn.net/xc635960736/article/details/7049863(未找到原始的引文) Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默 ...

最新文章

  1. 【1024】阿里开源项目汇总
  2. 计算机网络--详述OSI七层模型与TCP/IP五层模型
  3. fragment在activity中的静态和动态用法_使用Matlab修改压缩Gif动态图片制作微信表情...
  4. java如何保证类不被回收_垃圾回收机制保证了Java程序不会出现内存溢出。( )
  5. kali2020.3 vm版本内核是多少_Zircon Fuchsia 内核分析 启动(内核初始化)
  6. 马化腾:卓越领导者的五种习惯(作出表率尤为重要)
  7. Python3爬虫教程-1.使用爬虫抓取网页上的一张图片
  8. Java之Base64
  9. linux下格式化SD卡
  10. Unity应该怎样学习
  11. 软碟通(UltraISO)9.7.6.3812单文件高级版
  12. docker使用docker compose file部署项目时,实现容器卷挂载,并对容器内文件夹赋予权限
  13. 数组的过滤方法filter()
  14. 基于Graphhopper的路线导航方案
  15. 记得十年前谷歌大量使用python_关于利用Python玩转百万答题
  16. Android 13新特性:自动清除剪贴板历史记录
  17. Android手机安装apk 提示应用未安装
  18. Java 中 HttpURLConnection 与 PoLA 法则
  19. win10 开始 开始全屏快捷键
  20. 【尽快更换Aegisub 3.3.2】记录一下关于win10更新给Aegisub 3.2.2带来的影响

热门文章

  1. UA MATH565C 随机微分方程V Markov Family的算子
  2. VC++保存绘制的图形-1
  3. win32汇编使用win32 api实现字符串拷贝
  4. Python爬虫入门教程石家庄链家租房数据抓取
  5. 【java设计模式】-00目录
  6. Python 虚拟环境:Virtualenv
  7. 数据类型的sizeof
  8. python中reduce是什么意思,python中的map和reduce有什么不同
  9. 二分类2x2对角矩阵准确率表达式
  10. 以下属于单例模式的优点的是_三、单例模式详解