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的运行 ...
随机推荐
- linux 查看磁盘占用情况
查看"/usr/local/"路径下,所有文件大小总和.只列出总和,不显示该路径下各子文件的大小. du -sh /usr/local/ 结果显示如下图: 如果要详细显示出各子文件 ...
- Tiny6410之重定位代码到SDRAM
在上一章中,将代码重定位到了SRAM中,但是这样的做法作用不大.正确的做法的是将代码重定位到更大的主存中,即DRAM.Tiny6410的DRAM控制寄存器最多只能支持两个同一类型的芯片.每个芯片最多可 ...
- 视频和字幕演示APK, 欢迎下载
视频和字幕合成的演示APK 移动视频处理, 小咖秀-美拍-秒拍需要的字幕合成功能 我们推出这个demo, 视频格式支持MP4,字幕支持SRT/ASS/LRC,字幕文件编码为UTF8格式. 欢迎定制视频 ...
- 【IE6的疯狂之五】div遮盖select的解决方案
IE6以及一下版本下,选择框Select会覆盖Div中的内容一般情况下,可以将显示的内容放到Iframe中,然后再显示框架内的内容.由于Iframe的可以显示在Select上层,就可以解决这个问题.不 ...
- linux for 使用
第一种:命令使用方法 例子1: cat test.txt 1 2 3 for i in $(cat test.txt) do echo $i done 例子2: for i in 1 2 3 4 do ...
- #数论-模运算#POJ 1150、1284、2115
1.POJ 1150 The Last Non-zero Digit #质因数分解+模运算分治# 先贴两份题解: http://www.hankcs.com/program/algorithm/poj ...
- 安卓activity之间值共享解决办法,tabhost之间共享父类值,字符串类型的转换,获取每一个listview的item
1.tabhost父类值共享的解决办法 dianzhanliebiao.java是传值页面,zhuyemian.java放的是tabhost,dianzhangaikuang.java是tabhost ...
- 5.Struts2的OGNL表达式
1.创建javaweb项目Struts2_Part4_OGNL并在WebRoot下的WEB-INF下的lib文件夹下添加如下jar文件 commons.jar commons.jar freemark ...
- C# 语言规范_版本5.0 (第12章 数组)
1. 数组 数组是一种包含若干变量的数据结构,这些变量都可以通过计算索引进行访问.数组中包含的变量(又称数组的元素)具有相同的类型,该类型称为数组的元素类型. 数组有一个“秩”,它确定和每个数组元素关 ...
- linode更换Linux内核教程(独家)
Linode服务器性价比高,最低套餐2G内存,享受每月2TB流量,机房40Gb带宽,每月供需10美元(Linode优惠链接).Linode用户创建vps服务器后,可在后台自定义Linux系统版本,包括 ...