一、延迟载入定义

        
       延迟载入,也叫懒载入,它是Hibernate为提高程序运行效率而提供的一种机制,即当仅仅有真正使用该对象的数据时才会创建。

说白了,所谓的延迟载入不是在load的时候去数据库载入数据。而是当我在应用程序中真正使用该数据时Hibernate才去查询、载入对应的数据。


二、延迟载入实现原理

        
       Hibernate中主要是通过代理(proxy)机制来实现延迟载入。即Hibernate丛数据库获取某一个对象数据时、获取某一 个对象的集合属性值时。或获取某一个对象所关联的还有一个对象时。因为没有使用该对象的数据。hibernate并非数据库载入真正的数据,而仅仅是为该对 象创建一个代理对象来代表这个对象。这个对象上的全部属性都是默认值;仅仅有在真正须要使用该对象的数据时才创建这个真实对象,真正从数据库中载入它的数据。
       如:
      User user=(User)session.load(clazz, id);
      System.out.println(user.getId());
      user.getName();
      运行前两句代码时直接返回的是代理对象,没有发送sql语句到数据库载入。这样生成的代理对象具有与真实对象同样的属性和方法,仅仅是在实例化的时候仅仅实例化了该对象的id,当真正使用该对象的其它属性和方法时(运行第三句代码),才创建真实的User实例,并发送sql语句到数据库中载数据,这样大大节省了内存。
 

三、延迟载入应用环境

       
        当我们要訪问的数据量过大时。明显用缓存不太合适, 由于内存容量有限 。为了降低并发量。降低系统资源的消耗,这时Hibernate用懒载入机制来弥补这样的缺陷,可是这仅仅是弥补而不是用了懒载入整体性能就提高了。
       

实现懒载入的条件:

       
       1 实体类不能是final的 
       2 能实现懒载入的对象都是被CGLIB(反射调用)改写的代理对象,所以不能是final修饰的
       3 需要asm,cglib两个jar包
       4 对应的lazy属性为true
       5 对应的fetch属性为select 

Hibernate实现的懒载入:


1、   通过Session.load()实现懒载入
       load(Object, Serializable):依据id查询 。查询返回的是代理对象。不会立马訪问数据库,是懒载入的。当真正去使用对象的时候才会訪问数据库。

      使用load()时假设在session关闭之后再查询此对象,会报异常:could not initialize proxy - no Session。处理办法:
      a.在session关闭之前初始化一下查询出来的对象:Hibernate.initialize(user);
      b.在web.xml中配置OpenSessionInView过滤器就可以解决
<!-- OpenSessionInView 配置。解决Hibernate延迟载入的问题 -->
  <filter>
   <filter-name>lazyLoadingFilter</filter-name>
   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  </filter>
 
<filter-mapping>
   <filter-name>lazyLoadingFilter</filter-name>
   <url-pattern>*.do</url-pattern>
  </filter-mapping>

2、   one-to-one(元素)实现了懒载入。

       在一对一的时候,查询主对象时默认不是懒载入。

即:查询主对象的时候也会把从对象查询出来。须要把主对象配制成lazy="true" constrained="true"  fetch="select"。此时查询主对象的时候就不会查询从对象。从而实现了懒载入。

 
3、   many-to-one(元素)实现了懒载入。
       多对一的时候,查询主对象时默认是懒载入。即:查询主对象的时候不会把从对象查询出来。多对一的时候,查询从对象时默认是懒载入。

即:查询从对象的时候不会把主对象查询出来。

       hibernate3.0中lazy有三个值,true。false,proxy,默认的是lazy="proxy".详细设置成什么要看你的需求。并非说哪个设置就是最好的。在<many-to-one>与<one-to-one>标签上:当为true时,会有懒载入特性,当为false时会产生N+1问题,比方一个学生相应一个班级,用一条SQL查出10个学生,当訪问学生的班级属性时Hibernate会再产生10条SQL分别查出每一个学生相应的班级.
fetch= 捉取方式:select=关联查询;join=连接表的方式查询(效率高),fetch=join时,lazy的设置将没有意义.
 
4、   one-to-many(元素)懒载入:默认会懒载入,这是必须的,是重经常使用的。

        一对多的时候。查询主对象时默认是懒载入。

即:查询主对象的时候不会把从对象查询出来。

须要配置主对象中的set集合lazy="false" 这样就配置成是不懒载入了。或者配置抓取方式fetch="join"也能够变成不懒载入。

 

四、总结

       
       依据以上总结我们发现,在Hibernate的延迟载入机制中,大部分是针对集合类型(关联映射设置多的一方延迟载入)的应用意义最为重大。由于这有可能使性能得到大幅度的提高。而Hibernate 的延迟载入(lazy load)本质上就是代理模式的应用。通过代理模式来减少系统的内存开销、提升应用的执行性能。Hibernate 充分利用了代理模式的这样的优势,并结合了 Javassist 或 CGLIB 来动态地生成代理对象。这更加添加了代理模式的灵活性。仅仅只是Hibernate 给这样的使用方法一个新名称:延迟载入。

不管怎样,分析、了解这些开源框架的实现能够更好的体会到这些经典设计模式的优势所在。



Hibernate 延迟载入的更多相关文章

  1. Hibernate中的session和load延迟载入矛盾问题,怎样解决?

    假设延迟载入出现session close的情况下 方法1.在web.xml中配置spring的openSessionInViewFilter <filter>  <filter-n ...

  2. hibernate 普通字段延迟载入无效的解决的方法

    关联对象的延迟载入就不说了.大家都知道. 关于普通字段的延迟载入,尤其是lob字段,若没有延迟载入,对性能影响极大.然而简单的使用 @Basic(fetch = FetchType.LAZY) 注解并 ...

  3. hibernate之4.延迟载入

    延迟载入: 仅仅有当使用以实体对象的属性(除主键属性外)时,才会发送查询语句到数据库 get不支持延迟载入 @Test public void getTest(){ Session session=n ...

  4. 50个Android开发技巧(02 延迟载入和避免反复渲染视图)

    当你在Application中创建复杂的布局时.页面的渲染过程也变得更加缓慢. 此时,我们须要利用 <include />标签(避免反复渲染)和 ViewStub类(延迟载入)来优化我们的 ...

  5. 原声JS瀑布流加延迟载入

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 延迟载入Dll(动态载入Dll)

    windows核心编程(第五版)20.3节的延迟载入Dll 延迟载入Dll技术出现的原因: 因为DLL的加载是比较浪费时间的,特别是大型软件加载,因此,这项技术是在应对软件初始化过程中避免浪费太多的时 ...

  7. 【java】itoo项目实战之hibernate 懒载入优化性能

    在做itoo 3.0 的时候,考评系统想要上线,就開始导入数据了,仅仅导入学生2万条数据,可是导入的速度特别的慢.这个慢的原因是由于导入的时候进行了过多的IO操作.可是导入成功之后,查询学生的速度更加 ...

  8. Hibernate 学习教程

    第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...

  9. Java面试-Hibernate总结

    1  Hibernate的检索方式 Ø  导航对象图检索(依据已经载入的对象.导航到其它对象. ) Ø  OID检索(依照对象的OID来检索对象. ) Ø  HQL检索(使用面向对象的HQL查询语言. ...

随机推荐

  1. poj1011 Sticks(DFS+剪枝)

    题目链接 http://poj.org/problem?id=1011 题意 输入n根棍子的长度,将这n根棍子组合成若干根长度相同的棍子,求组合后的棍子的最小长度.这题是poj2362的加强版,思路与 ...

  2. jquery选择器详细说明

    jquery中选择器感觉是用的特别多并且特别方便的一个方法,今天就在这里详细的记载下大多数常用的选择器,一起学习探讨. 首先介绍的是css3的选择器,其中包括了标签选择器(div),ID选择器(#ID ...

  3. PHP视频教程 字符串处理函数(二)

    1.字符串输出:echo()输出一个或者多个字符串 2.截取 chunk_split(); 3.

  4. PHP 笔记——Web页面交互

    一.客户端数据提交方法 客户端浏览器的数据通常使用 GET.POST 方式提交到服务器. 1.GET方式 GET方式指直接在URL中提供上传数据或者通过表单采用GET方式上传. http://url? ...

  5. [Usaco2015 Feb]Censoring --- AC自动机 + 栈

    bzoj 3940 Censoring 题目描述 FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S. 他有一个包含n个单词的列表,列表里的n个单词记为T1......Tn. ...

  6. 【BJOI2014】大融合【LCT】

    闲着没事写篇题解 传送门 LCT维护子树的模板题 树链剖分中,子树可以用dfs序维护.但LCT你总不可能动态维护dfs序啊 LCT之所以不能直接维护子树,是因为LCT只能维护它的重儿子.我们把这棵子树 ...

  7. 没有调用PageHelper.startPage()分页方法,最后还是执行了PageHelper分页方法的原因

    SELECT * FROM ( SELECT TMP_PAGE.*, ROWNUM ROW_ID FROM ( SELECT * FROM ( SELECT A.*, ROWNUM RN FROM ( ...

  8. bzoj 1098

    对于关系,看其是否是“等价关系”,即满足:自反,传递,对称. 如果是可以用并查集来连接等价类. 这道题是求原图补集的联通快个数,考虑原图度最少的点(由鸽巢原理,最多为2*e/n个). 先将未与其连边的 ...

  9. bzoj 1014 LCP 二分 Hash 匹配

    求同一字符串的两个后缀的最长公共前缀. 将字符串按位置放到Splay中维护(每个节点还维护一下该子树的hash),然后二分前缀的长度,用splay计算出指定范围的hash,按hash是否相等来判断是否 ...

  10. bzoj 1625: [Usaco2007 Dec]宝石手镯

    Description 贝茜在珠宝店闲逛时,买到了一个中意的手镯.很自然地,她想从她收集的 N(1 <= N <= 3,402)块宝石中选出最好的那些镶在手镯上.对于第i块宝石,它的重量为 ...