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的运行 ...
随机推荐
- MAC OS U 盘制作与安装方法
伴随着 iMac 5K Retina 和新的 Mac mini 等硬件的发布,苹果终于都推出了 OS X Yosemite 系统正式版了!相信很多人都已经用上.不过对于一些不想升级,而是打算「全新安装 ...
- SUSElinux的pam模块中$ISA变量的作用
目的:限制非wheel用户切换至root 方法:vi /etc/pam.d/su文件,增加如下两行 auth sufficient /lib/security/pam_rootok.soauth re ...
- Python基础之列表
列表的内置方法 1.append() 描述:用于在列表末尾添加新的对象. 示例: msg_list=["aaaa","bbbbb","cccccc&q ...
- 修改searchBar的返回按钮的显示文字
#pragma mark 搜索框的代理方法,搜索输入框获得焦点(聚焦) - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { ...
- java操作mongodb——更新数据
Java中可以通过updateOne,updateMany,replaceOne方法进行集合的文档更新.但是 _id 是不能更新的 updateOne只会更新一条数据,即使通过Filters.lt(& ...
- .net XML操作
一.常规介绍 //初始化一个xml对象 XmlDocument xml = new XmlDocument(); //加载xml文件 xml.Load("文件路径"); //读取指 ...
- ubuntu 14.04—解决软件中心进度条卡死的问题
软件中心下载安装软件进度条卡住了,这时候解决方法为: 先解锁: sudo rm -rf /var/lib/dpkg/lock 如果此时开启软件中心,发现进度还在, 那么我们需要找到相关的进程关闭他,使 ...
- 一个view相对于屏幕或者另外一个view 的坐标
如果想知道一个view相对于屏幕或者另外一个view 的坐标,那么可以通过如下的方法得到: UIWindow * window=[[[UIApplication sharedApplication] ...
- springmvc获取jar中的静态资源与jar包中的资源互相引用问题
1.首先看jar中的文件位置 2.在web工程中引用该jar 并且在springmvc文件中配置路径 如果有多个路径可用逗号隔开 3.在web工程找jsp页面如何引用 这样就可以了 关于jar中的资源 ...
- linux下安装tomcat,并设置自动启动
在linux系统下,设置某个服务自启动的话,需要在/etc/rcX.d下挂载,还要在/etc/init.d/下写启动脚本的 在/etc/init.d/下新建一个文件tomcat(需要在root权限下操 ...