一.延迟加载的概念

当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,表示立即加载。

@Test

public void loadDept() {

// 获取Session对象

Session session = HibernateUtil.currentSession();

// 如果通过load方式加载Dept对象

Dept dept=(Dept)session.load(Dept.class, 12);

      // 关闭session

HibernateUtil.closeSession();

}

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

02.延迟加载案例:

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

@Test

public void loadDept() {

// 获取Session对象

Session session = HibernateUtil.currentSession();

// 如果通过load方式加载Dept对象

session.load(Dept.class, 12);

// 关闭session

HibernateUtil.closeSession();

}

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

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

01.立即加载案例:

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

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

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

   @Test

public void loadDept() {

// 获取Session对象

Session session = HibernateUtil.currentSession();

// 如果通过load方式加载Dept对象

Dept dept=(Dept)session.load(Dept.class, 12);

// 关闭session

HibernateUtil.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,或者不写的话(取默认值),那么执行以下语句:

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

输出结果:

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

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

控制台输出结果:

转:http://www.cnblogs.com/heyongjun1997/p/5775033.html

谢!

Hibernate之lazy延迟加载(转)的更多相关文章

  1. Hibernate之lazy延迟加载

    一.延迟加载的概念 当Hibernate从数据库中加载某个对象时,不加载关联的对象,而只是生成了代理对象,获取使用session中的load的方法(在没有改变lazy属性为false的情况下)获取到的 ...

  2. Hibernate中的延迟加载及fetch

    Hibernate中的延迟加载 1.类级别的查询策略: lazy  :  true(默认值) false(立即加载) 2.多对一关联的查询策略: lazy:  proxy(默认值) no-proxy ...

  3. Hibernate是如何延迟加载的

    Hibernate是如何延迟加载的 2011-12-24 13:58 242人阅读 评论(0) 收藏 举报 hibernatespringinterceptordao数据库integer Hibern ...

  4. hibernate中lazy的使用

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

  5. Hibernate学习之延迟加载

    转自:http://www.cnblogs.com/xiaoluo501395377/p/3371776.html 在hibernate中我们知道如果要从数据库中得到一个对象,通常有两种方式,一种是通 ...

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

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

  7. Lazy 延迟加载

    问题:最近遇到一个项目遇到一个问题(很久的项目,现阶段主要维护),程序初始化的时候比较慢,最后查原因的时候发现是因为一个类的构造方法里面有些逻辑, 解决办法:希望在使用的时候再进行加载,最后想到了延迟 ...

  8. 【Hibernate】浅析hibernate中的延迟加载

    1 简介 在使用一些查询方法时,方法执行了,但是并没有立刻发送SQL语句查询数据库.而是在访问对象的getXxx方法时候才触发SQL执行加载对象数据.这种机制就称为延迟加载. 2 优点 延迟加载主要是 ...

  9. AutoWired注解和Lazy延迟加载

    一.代码截图: @Lazy是延迟加载的意思, 容器启动时不创建对象, 当从容器中需要获取此对象时才创建. @Lazy//@Lazy注解可以用在类上, 还可以用在普通方法上,还可以用在构造方法上,还可以 ...

随机推荐

  1. Invalid Image Path - No image found at the path referenced under key "CFBundleIconFile": Icon.png

    I got the same error when uploading my app. Moving all icon files to the Asset Catalog works if your ...

  2. 那些年做过的 .NET Web 项目和 iOS 之路的一些思考

    从2010年3月份出来工作到2015年初,做过的大大小小的 .NET Web 项目如下: (1)售楼系统产品    「Role: Team Member」 (2)中弘合同管理系统    「Role: ...

  3. angularjs + seajs构建Web Form前端(三) -- 兼容easyui

    回顾 在上一章中使用了angular实现了ajax form和树形结构,经过以上两章对于angular的大致使用,对于angular也有了初步的认识,接下来的内容只会对angular的一些用法做简单的 ...

  4. ps图像渐变

    整理自:http://zhidao.baidu.com/question/16374167.html 1.用ps打开图片 2.在切换至英文输入法状态下(下面的操作均如此)按q 快捷键q的作用是切换标准 ...

  5. c++ 全局变量初始化的一点总结

    注意:本文所说的全局变量指的是 variables with static storage,措词来自 c++ 的语言标准文档. 什么时候初始化 根据 C++ 标准,全局变量的初始化要在 main 函数 ...

  6. 让我们一起Go(十一)

    前言: 今天又要继续了,当初自己的挖的坑必须得填啊,尽管天气非常滴热,但是丝毫无法阻挡我填坑的热情,那么,我们继续让我们一起Go!!! 定义方法: 这里我们要来看看Golang中的(Methods)方 ...

  7. java攻城狮之路(Android篇)--MP3 MP4、拍照、国际化、样式主题、图片移动和缩放

    一.MP3播放器 查看Android API文档可以看到MediaPlayer状态转换图: 练习: package com.shellway.mp3player; import java.io.Fil ...

  8. 论文第4章:iOS绘图平台的实现

    面向移动设备的矢量绘图平台设计与实现 Design and Implementation of Mobile Device-oriented Vector Drawing Platform 引用本论文 ...

  9. Spring MVC 3.x 基本配置

    WEB-INF/web.xml 例1 <?xml version="1.0" encoding="UTF-8"?> <web-app xmln ...

  10. 固态硬盘寿命实测让你直观SSD寿命!--转

    近年来,高端笔记本及系列上网本越来越多的采用固态硬盘来提升整机性能,尽管众所周知固态硬盘除 了在正常的使用中带来更快速度的体验外,还具有零噪音.不怕震动.低功耗等优点,但大家对固态硬盘的寿命问题的担忧 ...