session.get()和session.load()之间的区别

通常,您会注意到Hibernate开发人员将session.get()session load()混合使用,您是否想知道有什么不同?何时应使用它们中的任何一个?

session.get()和session.load()之间的区别

实际上,当然,这两个函数都用于检索具有不同机制的对象。

1. session.load()

  • 它将始终返回“ proxy ”(休眠术语),而无需访问数据库。 在Hibernate中,proxy是具有给定标识符值的对象,其属性尚未初始化,它看起来像一个临时的伪对象。
  • 如果未找到任何行,则将引发ObjectNotFoundException

2. session.get()

  • 它总是命中数据库并返回真实对象,该对象代表数据库行,而不是代理。
  • 如果未找到任何行,则返回null

关于性能

Hibernate出于某种原因会创建任何东西,当您进行关联时,通常是从数据库中获取检索对象(持久实例)并将其分配为对另一个对象的引用,只是为了维护关系。 让我们来看一些示例,以了解在什么情况下应该使用session.load()

1. session.get()

例如,在一个Stock应用程序中,Stock和StockTransactions应该具有“一对多”关系,当您要保存一个股票交易时,通常会声明以下内容

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对象,所有保存库存交易记录的东西吗? 毕竟,您只需要将Stock的ID作为对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不会访问数据库(输出中没有select语句)来检索Stock对象,它将返回一个Stock代理对象–一个具有给定标识值的伪造对象。 在这种情况下,代理对象足以保存股票交易记录。

例外

在例外情况下,请参见示例

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());

它将始终返回具有给定标识值的代理对象,即使该标识值在数据库中不存在。 但是,当您尝试通过从数据库检索代理的属性来初始化代理时,它将使用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

如果在数据库中找不到标识值,它将始终返回null。

结论

并非总是有正确的解决方案,您必须了解两者之间的区别,并确定哪种方法最适合您的应用程序。

翻译自: https://mkyong.com/hibernate/different-between-session-get-and-session-load/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值