Hibernate中session.get()和session.load()的区别
-- 翻译自https://www.mkyong.com/hibernate/different-between-session-get-and-session-load/
很多时候你会发现,使用Hibernate的开发人员会混淆session.get()和session.load()的用法,你是否理解这两个方法的区别并知道在什么时候使用正确的方法呢?
实际上,两个方法都是用来从数据库获取对象,只不过实现机制不一样而已。
1. session.load()
- 这种方式总是会返回一个代理而不是真正得去查询数据库。 在Hibernate里面,代理是一个依据ID值获取到的对象,该对象的属性还没有初始化,它看起来就是一个临时的虚拟对象而已。
- 如果load方法没有找到数据,就会抛出ObjectNotFoundException.
2. session.get()
- 这种方式总是会去数据库查询数据并返回一个真实的对象,该对象就代表数据库中的一行而非代理。
- 如果没有找到数据就会返回null.
性能方面的区别
由于某些原因,Hibernate会创建一些对象,当你做关联查询的时候,为了维护对象之间的关系,一般来说你会从数据库中拿到一个对象(持久化的实例)并把该对象作为一个引用指向另一个对象。我们来看一个例子来让大家理解什么情况下我们应该使用session.load().
1. session.get()
拿一个股票的应用来说,股票跟股票交易之间应该是一对多的关系,当你保存一次股票交易的时候,一般来说我们会写如下的代码:
Stock stock = (Stock)session.get(Stock.class, new Integer(2));
StockTransaction stockTransactions = new StockTransaction();
//set stockTransactions detail
stockTransactions.setStock(stock);
session.save(stockTransactions);
输出:
Hibernate:
select ... from mkyong.stock stock0_
where stock0_.STOCK_ID=?
Hibernate:
insert into mkyong.stock_transaction (...)
values (?, ?, ?, ?, ?, ?)
用session.get(), Hibernate会查询数据库以获取Stock对象,并把该对象作为一个引用指向StockTransaction对象。然而,保存流程数据的操作是很耗费资源的,如果一个小时内有成千上万次股票交易,你认为有必要每次都去查询数据库,去首先拿到Stock的真实对象然后把StockTransaction保存到数据库中吗?毕竟来说,你只是需要一个Stock的对象来让StockTransaction引用而已。
2. session.load()
在上面的应用场景中,session.load()会是一个好的解决方案,让我们来看一个例子:
Stock stock = (Stock)session.load(Stock.class, new Integer(2));
StockTransaction stockTransactions = new StockTransaction();
//set stockTransactions detail
stockTransactions.setStock(stock);
session.save(stockTransactions);
输出:
Hibernate:
insert into mkyong.stock_transaction (...)
values (?, ?, ?, ?, ?, ?)
使用session.load()方式,Hibernate不会查询数据库(输出的SQL里面没有select语句)来获取Stock对象,这种方式会返回一个Stock的代理对象 - 一个依据给定的ID值得虚假对象。这这种场景中,一个代理对象就足够用来保存股票交易的记录了。
异常方面的区别
session.load()
Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy //initialize proxy, no row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());
load方法总是会依据给定的ID值来返回一个代理对象,哪怕这个ID值甚至都不存在于数据库。然而,当Hibernate试图从数据库中获取属性来初始化该代理对象的时候,它就会使用select语句来从数据库查询数据,如果没有找到任何数据行,就会抛出ObjectNotFoundException了
org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.mkyong.common.Stock#100]
session.get()
//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100));
System.out.println(stock.getStockCode()); //java.lang.NullPointerException
与load方法不一样,如果在数据库中没有找到数据,get方法会返回null.
总结:
关于这两个方法的选择没有一成不变的解决方案,你必须要首先理解这两种方法的区别和联系,然后才能决定哪种方式更适合你的应用场景。
PS:第一次翻译国外网站的文章,感觉真是费力,本人英语水平有限,还请各位多多谅解。其实关于session.get()和session.load()的区别,只要记住两点就好了:
1. load方法支持延迟加载而get方法则不会。
2. load方法在没找到数据的时候会抛出ObjectNotFoundException而get方法则会返回空
Hibernate中session.get()和session.load()的区别的更多相关文章
- Hibernate的Session的get()和load()方法区别
hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别. get Session接口提供了4个重载的get方法,分别通过“持 ...
- Hibernate中两种获取Session的方式
转自:https://www.jb51.net/article/130309.htm Session:是应用程序与数据库之间的一个会话,是hibernate运作的中心,持久层操作的基础.对象的生命周期 ...
- hibernate中save()、get()、load()、update()、saveorupdate()、merge()等方法
1.save()方法 直接传个user对象 session.save(user); 2.get()方法和load()方法 get(): 传id session.get(UserInfo. ...
- hibernate中openSession()跟getCurrentSession()方法之间的区别
Hibernate openSession() 和 getCurrentSession的区别 getHiberanteTemplate .getCurrentSession和OpenSession 采 ...
- hibernate中save、update、saveOrUpdate的区别
saveOrUpdate如果hibernate-mapping配置的主键已存在,就不会新增,会更新. ------------------------------------------------- ...
- hibernate中的SessionFactory,Session分别表示什么啊?如何理解?
Session接口 Session接口对于Hibernate 开发人员来说是一个最重要的接口.然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会 ...
- 关于hibernate中的session与数据库连接关系以及getCurrentSession 与 openSession() 的区别
1.session与connection,是多对一关系,每个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用. 2.多个sessi ...
- 关于hibernate中对象的三种状态分析
一,首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load ...
- 对象在hibernate中的状态
首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load() ...
- Hibernate中的对象状态,及自动更新原因
Hibernate的对象有三种状态,分别为:瞬时状态 (Transient). 持久化状态(Persistent).游离状态(Detached).对它的深入理解,才能更好的理解hibernate的运行 ...
随机推荐
- python 数组过滤
arr = [1,2,3,4,5,6,7,8,None]arr = [elem for elem in arr if elem != None]
- java list<string>集合 传递值给js的数组
转载地址:http://blog.sina.com.cn/s/blog_611f65fd0100msc6.html. 1.Action 中代码 List result = n ...
- Lua 数据类型和 Redis 数据类型之间转换
当 Lua 通过 call() 或 pcall() 函数执行 Redis 命令的时候,命令的返回值会被转换成 Lua 数据结构. 同样地,当 Lua 脚本在 Redis 内置的解释器里运行时,Lua ...
- 【IE6的疯狂之六】li在IE中底部3像素的BUG(增加浮动解决问题)
今天开发项目中碰到一个li在IE中的BUG,先来看设计原型(如图:) 两个红色中间是<li>1px的底边框: 我写的代码如下: ============================== ...
- C# lock关键词/lock语句块、线程锁
一.lock关键词说明 1. lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 2. lock 语句块锁定,功能等同于 Monitor.Enter(obj): ...
- 【POJ2186】受牛仰慕的牛
受牛仰慕的牛(popular cows) 每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有N(1<=N<=10,000)头牛的牛群中,给你M(1<=M<=50,00 ...
- 【jquery、XML】jquery通过按钮使打开select
<select> <option>aaaaa</option> <option>bbbbb</option> <option>c ...
- ubuntu 14.04—解决软件中心进度条卡死的问题
软件中心下载安装软件进度条卡住了,这时候解决方法为: 先解锁: sudo rm -rf /var/lib/dpkg/lock 如果此时开启软件中心,发现进度还在, 那么我们需要找到相关的进程关闭他,使 ...
- UNIX基础--Manual Pages
联机手册 Manual Pages 最详细的使用说明文档莫过于 FreeBSD 里的联机手册了. 几乎每一个程序都会附上一份简短说明, 以介绍这个程序的的基本功能以及参数的用法. 我们能通过 man ...
- Python基础(十一)-面向对象
三种编程范式: 1.函数式编程:函数指数学意义上的函数 由于命令式编程语言也可以通过类似函数指针的方式来实现高阶函数,函数式的最主要的好处主要是不可变性带来的.没有可变的状态,函数就是引用透明(Ref ...