Hibernate中Session.get()/load()之区别
原文链接http://sunxin1001.iteye.com/blog/292090
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方法。
返回数据对象。
hibernate中get方法和load方法的根本区别在于:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在
数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存
在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于
session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不
存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。
对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。
对
于第2点,虽然好多书中都这么说:“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在session缓存中找到了该id对应的对
象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该
代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体
数据。
3。胡说八道,前面已经讲了,get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
Hibernate中Session.get()/load()之区别的更多相关文章
- Hibernate中get()和load()方法区别
get和load方式是根据id取得一个记录下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来. 1.从返回结果上对比:load方式检索不到的话会抛出org.hibernat ...
- Hibernate中get()和load()的区别
Hibernate中根据Id单条查询获取对象的方式有两种,分别是get()和load(),来看一下这两种方式的区别. 1. get() 使用get()来根据ID进行单条查询: User user=se ...
- 【hibernate】Hibernate中get()和load()的区别
Hibernate中根据Id单条查询获取对象的方式有两种,分别是get()和load(),来看一下这两种方式的区别. 1. get() 使用get()来根据ID进行单条查询: 1 User user= ...
- Hibernate中get()与load()的区别,以及关于ThreadLocal的使用方法
一.get方法和load方法的简易理解 (1)get()方法直接返回实体类,如果查不到数据则返回null.load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时 ...
- Hibernate 中 get()和load()的区别
一.1.程序检索数据库中不存在的OID: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回nu ...
- hibernate中Session的load和get方法的区别是什么?
主要有以下三项区别: ① 如果没有找到符合条件的记录,get方法返回null,load方法抛出异常. ② get方法直接返回实体类对象,load方法返回实体类对象的代理. ③ 在Hibernat ...
- Hibernate中get和load的区别
get获取的对象立即执行sql查询数据库中当前实体表中的数据,如果外键关联的其他实体表如果配置了懒加载关闭,则也会查询出外键关联的其他实体表中的数据,否则外键关联的其他实体表则以代理对象表示(称其为代 ...
- Hibernate中Session的get和load
hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别.测试版本:hibernate 4.2.0. get Session接 ...
- [转]Hibernate中Session的get和load
hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别.测试版本:hibernate 4.2.0. get Session接 ...
随机推荐
- ICEM-一种网格画法的思考
原视频下载链接:https://pan.baidu.com/s/1kV4Zj3x 密码: uthc
- Software Engineering Continuous Integration Eclipse Mylyn
- Git push origin dev-rgq-istokenstatus 【dev-rgq-istokenstatus -> dev-rgq-istokenstatus】
RenGuoQiang@PC-RENGUOQIANG MINGW64 /d/zgg/zgg-crm (dev-rgq-istokenstatus) $ git push origin dev-rgq- ...
- [转]白话HTTP短连接中的Session和Token
我经常想象并怀念三十年前那原始而美好的互联网旧时光, 工作很轻松, 生活很悠闲. 上班的时候偶尔有些HTTP的请求发到我这里, 我简单的看一下, 取出相对应的html文档,图片,发回去就可以了, 然后 ...
- Swift编码总结7
1.Git 打Tag: 命令也就下面两条,看看就会了. 2.字符串转Model:JSONDecoder http://www.cocoachina.com/ios/20180612/23771.htm ...
- Oracle current redo.log出现坏块后的不完全恢复案例一则
1异常出现 8月30日下午2时左右,接同事电话,说数据库异常宕机了,现在启动不了. 2初步分析 我让现场把alert.log发过来,先看看是什么问题. 关于ORA-00353和ORA-0 ...
- 测试从应用到DB的准确的网络延迟
最近几大云厂商把底层的基础设施包装起来后,通过Ping等很难知道真正的网络延迟了,因为通过ping还没到db都返回了,如何知道从应用到db的真正网络延迟呢? 用我的脚本 #!/bin/bash m= ...
- maven环境搭建教程
1.下载和解压 访问 maven.apache.org .点击download 下载对应系统的文件,window下载bin的zip文件. maven需要java1.7jdk支持,如果jdk没有 ...
- jqGrid设置单选
beforeSelectRow: function() { $(this).jqGrid('resetSelection'); return true; }
- 九、Spring中使用@Value和@PropertySource为属性赋值
首先回顾下在xml中我们是如何为spring的bean进行属性赋值呢? 大体是这样的 <bean id="person" class="com.atguigu.be ...