Hibernate中Session.get()方法和load()方法的详细比较

 更新时间:2019年03月29日 16:10:02   作者:徐刘根   我要评论

今天小编就为大家分享一篇关于Hibernate中Session.get()方法和load()方法的详细比较,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

一、get方法和load方法的简易理解

(1)get()方法直接返回实体类,如果查不到数据则返回null。load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时,如果没有数据不存在,就会抛出个org.hibernate.ObjectNotFoundException异常

(2)load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找),等后面使用这个代理对象操作的时候,才到DB中查询,这就是我们常说的 load在默认情况下支持延迟加载(lazy)

(3) get先到缓存(session缓存/二级缓存)中去查,如果没有就到DB中去查(即马上发出sql)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)

(4)get和load查询数据库

1. 如果查询不到数据,get 会返回 null,但是不会报错, load 如果查询不到数据,则报错ObjectNotFoundException

2. 使用get 去查询数据,(先到一级/二级)会立即向db发出查询请求(select ...), 如果你使用的是 load查询数据,(先到一级、二级))即使查询到对象,返回的是一个代理对象,如果后面没有使用查询结果,它不会真的向数据库发select ,当程序员使用查询结果的时候才真的发出select ,这个现象我们称为懒加载(lazy)

3. 通过修改配置文件(*.hbm.xml文件),我们可以取消懒加载

<class name="Employee" lazy="false" table="employee"> 

二、结合缓存技术比较get和load区别

注:一级缓存是必须有的,二级缓存是配置的可选(这里解释的时候默认有二级缓存)

1.get在查询的时候首先到一级缓存(session级缓存)中查找,没有的话进入二级缓存(介于内存与硬盘之间) 如果二级缓存还没有则直接进入数据库中查询!查询到并将查询的结果放入二级缓存!查询不到不会报错 如果查询同一条数据,get会出现在第一次查询的时候会出查询数据库 但是第二次的时候会直接沿着一级缓存、二级缓存查找可以找到!

2.load在查询的时候也是先到一级缓存中查找,如果找到则不会查询数据库,如果找不到则依次到二级缓存查找,如果二级缓存中没有查找的数据,get方法会根据是否要立即利用查询的结果,如果不利用的话则停止查找;如果要立即使用的话则会进入数据库中查找;查询到并将查询的结果放入二级缓存!查询不到则会报错!

三、深入区别get方法和load方法

(1)hibernate中get方法和load方法的根本区别在于:

1.如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。

2.由于 session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。

3.对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。

4.get方法如果在session缓存中找到了该id 对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

5.get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。

(2)总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

四、load和get方法的使用

/**
 * 比较load方法和get方法的区别
 **/
 public static void CompareLoadAndGet(){
 Configuration configuration = new Configuration().configure();
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 Session session = sessionFactory.openSession();
 Transaction ts = null;
 Transaction ts1 = null;
 try {
 /**
 * 使用load方法
 **/
 ts = session.beginTransaction();
 Employee emp= (Employee) session.load(Employee.class, 9);
 System.out.println("load方法获取的员工姓名:"+emp.getName());
 ts.commit();
 /**
 * 使用get方法
 **/
 ts1 = session.beginTransaction();
 Employee emp1= (Employee) session.get(Employee.class, 9);
 System.out.println("get方法获取的员工姓名:"+emp1.getName());
 ts1.commit();
 } 
// catch (Exception e) {
// if(ts!=null){
// ts.rollback();
// }
// }
 finally{
 if(session!=null&&session.isOpen()){
 session.close();
 }
 }
 }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • CountDownLatch源码解析之countDown()

    CountDownLatch源码解析之countDown()

    这篇文章主要为大家详细解析了CountDownLatch源码之countDown方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • 基于RabbitMQ几种Exchange 模式详解

    基于RabbitMQ几种Exchange 模式详解

    下面小编就为大家带来一篇基于RabbitMQ几种Exchange 模式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • java图形界面之布局设计

    java图形界面之布局设计

    这篇文章主要介绍了java图形界面之布局设计的相关资料,需要的朋友可以参考下
    2015-06-06
  • 浅析Java验证码生成库JCaptcha

    浅析Java验证码生成库JCaptcha

    JCaptcha 是一个用来生成验证码的开源Java类库,使用起来也是非常的简单方便。本文通过代码实例介绍了JCaptcha类库。
    2016-07-07
  • Java中前台往后台传递多个id参数的实例

    Java中前台往后台传递多个id参数的实例

    下面小编就为大家带来一篇Java中前台往后台传递多个id参数的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 在Maven下代理服务器设定的方式

    在Maven下代理服务器设定的方式

    今天小编就为大家分享一篇关于在Maven下代理服务器设定的方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • spring boot结合Redis实现工具类的方法示例

    spring boot结合Redis实现工具类的方法示例

    这篇文章主要介绍了spring boot结合Redis实现工具类的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • 图文详解mybatis+postgresql平台搭建步骤

    图文详解mybatis+postgresql平台搭建步骤

    从头开始搭建一个mybatis+postgresql平台,这篇文章主要介绍了图文详解mybatis+postgresql平台搭建步骤,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • 教大家使用java实现顶一下踩一下功能

    教大家使用java实现顶一下踩一下功能

    这篇文章主要教大家如何使用java实现顶一下踩一下功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • htmlcleaner使用方法及xpath语法初探

    htmlcleaner使用方法及xpath语法初探

    HtmlCleaner是一个开源的Java语言的Html文档解析器。HtmlCleaner能够重新整理HTML文档的每个元素并生成结构良好(Well-Formed)的 HTML 文档
    2015-08-08

最新评论