Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。
其区别在于: 如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。 Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。

load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。

Session在加载实体对象时,将经过的过程: 首先,Hibernate中维持了两级缓存。第一级缓存由Session实例维护,其中保持了Session当前所有关联实体的数据,也称为内部缓存。而第二级缓存则存在于SessionFactory层次,由当前所有由本SessionFactory构造的Session实例共享。出于性能考虑,避免无谓的数据库访问,Session在调用数据库查询功能之前,会先在缓存中进行查询。首先在第一级缓存中,通过实体类型和id进行查找,如果第一级缓存查找命中,且数据状态合法,则直接返回。
之后,Session会在当前“NonExists(把无效的条件写成一个黑名单,既然无效,那么也没必要再查下去)”记录中进行查找,如果“NonExists”记录中存在同样的查询条件,则返回null。“NonExists”记录了当前Session实例在之前所有查询操作中,未能查询到有效数据的查询条件(相当于一个查询黑名单列表)。如此一来,如果Session中一个无效的查询条件重复出现,即可迅速作出判断,从而获得最佳的性能表现。
对于load方法而言,如果内部缓存中未发现有效数据,则查询第二级缓存,如果第二级缓存命中,则返回。

如在缓存中未发现有效数据,则发起数据库查询操作(Select SQL),如经过查询未发现对应记录,则将此次查询的信息在“NonExists”中加以记录,并返回null。

根据映射配置和Select SQL得到的ResultSet,创建对应的数据对象。 将其数据对象纳入当前Session实体管理容器(一级缓存)。 执行Interceptor.onLoad方法(如果有对应的Interceptor)。 将数据对象纳入二级缓存。 如果数据对象实现了LifeCycle接口,则调用数据对象的onLoad方法。 返回数据对象。
/** *//**   * load()方法的执行顺序如下:   * a):首先通过id在session缓存中查找对象,如果存在此id的对象,直接将其返回   * b):在二级缓存中查找,找到后将 其返回。   * c):如果在session缓存和二级缓存中都找不到此对象,则从数据库中加载有此ID的对象   * 因此load()方法并不总是导致SQL语句,只有缓存中无此数据时,才向数据库发送SQL!     */
 /** *//**   * 与get()的区别:   * 1:在立即加载对象(当hibernate在从数据库中取得数据组装好一个对象后   * 会立即再从数据库取得数据此对象所关联的对象)时,如果对象存在,   * load()和get()方法没有区别,都可以取得已初始化的对象;但如果当对   * 象不存在且是立即加载时,使用get()方法则返回null,而使用load()则   * 抛出一个异常。因此使用load()方法时,要确认查询的主键ID一定是存在   * 的,从这一点讲它没有get方便!   * 2:在延迟加载对象(Hibernate从数据库中取得数据组装好一个对象后,   * 不会立即再从数据库取得数据组装此对象所关联的对象,而是等到需要时,   * 都会从数据库取得数据组装此对象关联的对象)时,get()方法仍然使用   * 立即加载的方式发送SQL语句,并得到已初始化的对象,而load()方法则   * 根本不发送SQL语句,它返回一个代理对象,直到这个对象被访问时才被   * 初始化。   */
get()----不支持LAZY
load()----支持LAZY
load和get一共是2个区别 先讲第一个 延迟加载  load是true而get是false 意 思就是 load采用的是延迟加载的方式 而get不是,hibernate思想是 既然这个方法支持延迟加载 他就认为这个对象一定在数据库存在,在你 声明 TFaq tfag2=(TFaq)sess.load(TFaq.class, 300); 这句时候,hibernate就干了一件事  1.查询session缓存 2.缓存中没有这个对象 就创建个代理 因为延迟加载需要代理来执行 所以就创建了个代理 ok 到此为止 这句话就干了个这个 并没有去数据库交互查询 当你使用这个对象 比如tfag2.getTfRtitle()或get方法时候 这个时候 hibernate就去查询二级缓存和数据库,数据库没有这条数据 就抛出异常 整个load方法调用结束 load没什么神奇 这就是他干过所有的事情
load方法讲完了 我在讲一下get方法工作原理 因为hibernate规定get方法不能使用延迟加载 所以和load还是不一样的 TFaq tfag2=(TFaq)sess.get(TFaq.class, 300); 在创建这条语句时候 我们看看hibernate干了哪些事 1.get方法首先查询session缓存 (session缓存就是hibernate的一级缓存 这个概念大家应该清楚吧 ) 2.get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象。 3.如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。 (这个代理实际就是空的对象 并没有去数据库查询得到的 我们叫代理对象,如果 去数据库查询了 返回到了这个对象 我们叫实体对象 就是这个对象真实存在)
我在总结性一句话这2者区别  get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库

----我测试过:
在使用session.get方法后如果把session关闭的话,也会出现懒加载异常。
那么只有在manytoone标签里配置 lazy="false"时异常才会解决。
也就是说上面转载的第3条不是那么正确:返回该代理对象不错,但是如果该对象没有加载实体数据,那么也会在用到时才会加载,即不会立即查询数据库或者二级缓存,那么你现在把session关闭,这个对行啊没有加载实体数据----才会出现懒加载异常。

装载自:http://blog.csdn.net/houjiyu243042162/article/details/27243029

Session中load/get方法的详细区别的更多相关文章

  1. Session中清除对象方法比较

    转载. https://blog.csdn.net/u014401141/article/details/51816308 Session中清除对象方法比较   http://blog.csdn.ne ...

  2. java中的compareto方法的详细介绍

    java中的compareto方法的详细介绍 Java Comparator接口实例讲解(抽象方法.常用静态/默认方法) 一.java中的compareto方法 1.返回参与比较的前后两个字符串的as ...

  3. session中load()跟get()的区别

    1.相同点:Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象. 2.区别在于: (1)如果未能发现符合条件的记录,get方法返回null,而l ...

  4. Hibernate session中的createCriteria方法

    在应用中获取session对象: Session session=  HibernateUtil.getSession(); List list=session.createCriteria(Mete ...

  5. java中的static方法和实例方法区别

    1.static方法是大家共享的资源,放在内存堆中,比如村里的河水,每个人都可以取,而且不管你创建多少个实例,该方法在内存中只有一个,节省内存空间, 而且访问速度也是比较快的. 2.实例方法就不同,它 ...

  6. php中的var_dump()方法的详细说明

    首先看看实例: <?PHP$a = "alsdflasdf;a";$b = var_dump($a);echo "<br>";//var_du ...

  7. java.lang.String中的trim()方法的详细说明(转)

    String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗? 一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱. 首先我直接反编译String ...

  8. vuex中mutation和action的详细区别

    const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } ...

  9. java中的compareto方法以及LIst列表排序的详细介绍【转】

    java中的compareto方法的详细介绍 javacompareTo  java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a=&quo ...

随机推荐

  1. 深入挖掘.NET序列化机制——实现更易用的序列化方案

    .NET框架为程序员提供了“序列化和反序列化”这一有力的工具,使用它,我们能很容易的将内存中的对象图转化为字节流,并在需要的时候再将其恢复.这一技术的典型应用场景包括[1] : 应用程序运行状态的持久 ...

  2. kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件

    小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...

  3. JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString

    JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString 如下示例: 直接写的a1就是一个Json对象,a2 就是一个Json对象字符串; 通 ...

  4. Sublime Text执行js

    Sublime Text执行js 在Build Sytem添加以下内容: { "cmd": ["node", "$file"], " ...

  5. HTTP学习二:Web应用中的HTTP

    1 HTTP连接 1.1 TCP连接对性能的影响 TCP三次握手如下图: 如上图,建立一次TCP连接要经过三个步骤.HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能. TCP影 ...

  6. 阿里云centos7搭建wordpress环境

    阿里云搭建wordpress系统 一.购买阿里云 二.安装php开发环境 1. https://www.apachefriends.org/zh_cn/index.html网站下载linux下的xam ...

  7. 【Win10 应用开发】人脸识别

    可能你会认为人脸识别用起来会很复杂,老周当初也这么想,但通过实际操作后,我发现非然. 经过微软封装的东西,向来都是复杂问题简单化,只要用得舒心,代码越少越好,用最少的代码做最多的事情,此为大师境界也. ...

  8. 深入理解DOM事件类型系列第五篇——文本事件

    × 目录 [1]change [2]textInput [3]input[4]propertychange[5]兼容 前面的话 如果DOM结构发生变化,触发的是变动事件:如果文本框中的文本发生变化,触 ...

  9. Android音频开发之AudioRecord录音实现

    前言: 其实在Android中录音可以用MediaRecord录音,操作比较简单.但是不能对音频进行处理.考虑到项目中做的是实时语音只能选择AudioRecord进行录音. 本文算是对AudioRec ...

  10. L2 Population 原理 - 每天5分钟玩转 OpenStack(113)

    前面我们学习了 VXLAN,今天讨论跟 VXLAN 紧密相关的 L2 Population. L2 Population 是用来提高 VXLAN 网络 Scalability 的. 通常我们说某个系统 ...