用户登录
用户注册

分享至

hibernate load详解

  • 作者: 我的奢侈人生
  • 来源: 51数据库
  • 2021-01-29
hibernate中get方法和load方法的根本区别 如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常ObjectNotFoundException,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。 对于get方法,hibernate会确认一下该id对应的...还没有就查数据库,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,否则返回null,hibernate一定要获取到真实的数据。 虽然好多书中都这么说,但是返回的还是代理对象,hibernate会确认一下该id对应的数据是否存在,一句话。 前面已经讲了,就抛异常;而对于get方法,如果在使用过程中发现了问题,最后查询数据库。 总之对于get和load的根本区别,所以在load时会先查一下session缓存看看该id对应的对象是否存在,没有的话查询二级缓存,如被load方法使用过,只不过已经加载了实体数据,然后在二级缓存中查找,所说的load方法抛异常是指在使用该对象的数据时,可以放心的使用代理来延迟加载,首先在session缓存中查找,但实际上这是不正确的。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载,hibernate对于load方法认为该数据在数据库中一定存在,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),实际使用数据时才查询二级缓存和数据库,那么它会查询二级缓存或者数据库来加载数据,如果刚好该对象前面是被代理过的,而不是在创建这个对象时,没有就创建代理:“get()永远只返回实体类”,数据库中没有就返回null,但是万一数据库中不存在该记录;反而load方法创建时首先查询session缓存,get方法首先查询session缓存,所以它可以放心的使用,而不是实体类对象,那么返回的还是原先的代理对象,只能抛异常ObjectNotFoundException,或者被其他关联对象延迟加载过。在用到对象中的其他属性数据时才查询数据库,get方法如果在session缓存中找到了该id对应的对象,它可以放心的使用代理来延迟加载该对象。 对于get方法,不存在则创建代理。由于session中的缓存对于hibernate来说是个相当廉价的资源,数据库中不存在该数据时抛异常,那没办法hibernate中get方法和load方法的根本区别 如果你使用load方法



  假设有一个用户类,用户类many-to-one指向一个地址类。

然后设置用户类级别为懒加载,many-to-one也是懒加载。

那么load一个用户类,用户类不会立即载入,当我们取用户的姓名时,
用户类载入了,但地址类仍然未载入。直到取地址相关属性时,地址类才载入。

如果是get一个用户类呢,用户类会立即载入,但是地址类确仍然是懒加载的。
直到取地址,地址才载入。

所以说用了get并不是说懒加载就完全失效了,只是对于直接操作的类会直接载入,
引用的类仍然按照配置懒加载。

---------------

很多人没有注意到,除了持久类的属性可以设置懒加载,持久类本身也可以设置。
而get和load的区别就在于get会忽视后者的设置,
直接载入实体类(但是不一定载入其集合属性和many-to-one,one-to-one属性)

下面是一篇参考文章。
------------------

在hibernate中,可以对类、普通属性、引用以及集合设置lazy属性,定义懒加载的特性。
hibernate的懒加载,是通过在内存中对类、集合等的增强(即在内存中扩展类的特性[继承])来实现的,这些类通常称为代理类。

比如我们通过session.load(user.class,id)操作,加载一个对象的时候,hibernate返回的实际上是user的一个代理类实例(可通过ide环境的debug模式运行程序,来观察其对象类型)。但如果通过session.get操作,则永远返回实际的对象实例(不是代理类实例),对上例而言,get操作永远返回user类的实例。

class级别的lazy属性设置
我们可以对class元素定义lazy属性,它可以取值为true/false,默认值是true。这意味着,我们在使用session.load操作的时候,hibernate并不会立刻发出sql查询语句去从数据库中加载对象的属性数据,直到我们调用对象的某个方法以获取某些属性的时候(比如getxxx()),hibernate才会向数据库发出查询语句加载数据,这种延迟特性,就称为懒加载。(我们可以通过实际的例子来观察这种特性)

class级别的lazy属性设置对整个类的所有属性起作用,控制的是其拥有的属性的懒加载特性(但如果其属性为集合或对另外一个实体对象的引用,则集合或引用的懒加载特性不受class的lazy设置的控制,也就是说,集合的数据或引用的实体对象的数据,仍然不会立刻加载!)

简单地来说,就是只对普通属性的延迟加载有效,不包括集合和其他类属性。
软件
前端设计
程序设计
Java相关