zoukankan      html  css  js  c++  java
  • session.load()和session.get()的区别

    Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
    1. 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。 
    2. load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),分情况讨论: 
    (1)若为true,则首先在Session缓存中查找,看看该id对应的对象 是否 存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象(除获取OID以外)的时候, 再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
    (2)若为false,就跟get方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。 
    这里get和load有两个重要区别: 
    如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。 

    load方法可返回没有 加载实体数据的代理类实例,而get方法永远返回有实体数据的对象。(对于load和get方法返回类型:好多书中都说:“get方法永远只返回实体 类”,实际上并不正确,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被 其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会 查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。)

    Java代码 
    1. Users user = (Users)session.load(Users.class, userId);   

    这句代码不会去执行数据库查询,只有用到user时才会去执行数据库查询。

    而:

    Java代码
    1. Users user = (Users)session.get(Users.class, userId);    

     则立即去执行数据库查询。 所以Users user = (Users)session.load(Users.class, userId);不会执行任何sql。

    注意:

    Java代码
    1. Users user = (Users)session.load(Users.class, userId);     
    2. System.out.println(user.getId());   

    上面这2句代码,不会去执行数据库操作。因为load后会在hibernate的一级缓存里存放一个map对象,该map的key就是userId的值,但是当你getId()时,它会去一级缓存里拿map的key值,而不去执行数据库查询。所以不会报任何错。不会执行任何数据库操作。

    并且注意:这两个方法的第二个参数id,它必须是实现了Java.io.Serializable接口,也就是可序列化的。

     

    /** *//**
      * 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

  • 相关阅读:
    RocketMQ学习笔记(14)----RocketMQ的去重策略
    RocketMQ学习笔记(13)----RocketMQ的Consumer消息重试
    RocketMQ学习笔记(12)----RocketMQ的Consumer API简介
    RocketMQ学习笔记(11)----RocketMQ的PushConsumer和PullConsumer
    RocketMQ学习笔记(10)----RocketMQ的Producer 事务消息使用
    RocketMQ学习笔记(9)----RocketMQ的Producer 顺序消息
    RocketMQ学习笔记(8)----RocketMQ的Producer API简介
    RocketMQ学习笔记(7)----RocketMQ的整体架构
    RocketMQ学习笔记(6)----RocketMQ的Client的使用 Producer/Consumer
    RocketMQ学习笔记(5)----RocketMQ监控平台rocketmq-console-ng的搭建
  • 原文地址:https://www.cnblogs.com/xijin-wu/p/5730104.html
Copyright © 2011-2022 走看看