load和get之Hibernate的延迟加载机制

本文探讨了Hibernate中load与get方法的区别。load方法假定数据一定存在,使用代理实现延迟加载,若数据不存在则抛出异常;get方法则会在数据不存在时返回null。load支持延迟加载,而get不支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Hibernate中:

如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所 以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常

ObjectNotFoundException。

   下面是使用load查询对象的时候,对象不存在的情况下的Hibernate处理机制。

   

 
 
  1. public void testQuertNotExistByLoadMethod(){ 
  2.         Session session = null
  3.         Transaction tran = null
  4.         Person p =null
  5.         try
  6.             session = FactorySession.getSession(); 
  7.             tran = session.beginTransaction(); 
  8.             tran.begin(); 
  9.             //使用了lazy,只有在正真使用的时候才加载数据对象 
  10.             //Hibernate延迟加载采用的是代理方式 
  11.             p=(Person)session.load(Person.class"不存在"); 
  12.             System.out.println(p.getPerName()); 
  13.             session.save(p); 
  14.             tran.commit(); 
  15.         } catch (Exception e) { 
  16.             tran.rollback(); 
  17.         } finally { 
  18.             FactorySession.closeSession(session); 
  19.         } 
  20.     } 

下面是调试情况下的截图:


使用load加载数据的时候,这里的id="不存在"在数据库中并不存在数据,将会抛出异常。


当使用get方法的时候当查询的数据数据库不存在的时候将返回null.

下面是通过查询数据库已有的数据,然后修改持久化数据,查看代理类的状态。


 
 
  1. public void testQuertNotExist(){ 
  2.         Session session = null
  3.         Transaction tran = null
  4.         Person p =null
  5.         try
  6.             session = FactorySession.getSession(); 
  7.             tran = session.beginTransaction(); 
  8.             tran.begin(); 
  9.             //采用load方法,获得已有的对象,然后进行更新 
  10.             p=(Person)session.load(Person.class"8aab8c8538a101310138a10132190001"); 
  11.             System.out.println(p.toString()); 
  12.             p.setCreatTime(new Date()); 
  13.             session.save(p); 
  14.             tran.commit(); 
  15.         } catch (Exception e) { 
  16.             tran.rollback(); 
  17.         } finally { 
  18.             FactorySession.closeSession(session); 
  19.         } 
  20.     } 

Person类的对象p是存在的,当程序运行到 System.out.println(p.toString()); 的时候控制台输出

 
 
  1. Hibernate: select person0_.perId as perId0_0_, person0_.perNamee as perNamee0_0_, person0_.creatTime as creatTime0_0_ from ext.dbo.Person person0_ where person0_.perId=? 
  2. Person [creatTime=2012-07-20 06:14:21.173, perId=8aab8c8538a101310138a10132190001perName=孙悟空] 
查看运行过程的代理类的信息: 

       代理类的target目标下的信息和查询到的信息一相同的。当更新持久化对象p的创建时间的时候由于traget不为空,表示Session缓存中存在对象,而且此刻p对象仍然在接收着Session的管理,所以可以控制台中显示出有更新语句的产生。       当然如果没有查询到数据这里的traget自然就为空了。 
 
 
  1. Hibernate: select person0_.perId as perId0_0_, person0_.perNamee as perNamee0_0_, person0_.creatTime as creatTime0_0_ from ext.dbo.Person person0_ where person0_.perId=? 
  2. Person [creatTime=2012-07-20 06:15:58.167, perId=8aab8c8538a101310138a10132190001, perName=孙悟空] 
  3. Hibernate: update ext.dbo.Person set perNamee=?, creatTime=? where perId=? 

get和load的根本区别:hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,就抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。load方法具有延迟加载的功能,而get方法没有。




本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/935844,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值