hibernate懒加载
懒加载要求Domain对象不能是final的,因为Hibernate需要生成一个继承自该Domain对象的类来实现懒加载。懒加载主要有三种:
1. 对象的懒加载
2. 关联集合的懒加载
3. 对象属性的懒加载
对象的懒加载
对象的懒加载就是在映射文件的class标签中设置lazy属性为true,这时,如果用session.load方法获取这个对象的话,Hibernate只返回一个代理对象,而不是真的去查询数据库,等到真正用到这个对象的时候,Hibernate才会去查询数据库。
关联集合的懒加载
关联集合的懒加载有多种:
1. 一对一映射懒加载
在一对一映射中,查询主对象时,Hibernate是不进行懒加载的,即使在映射文件中设置了主对象的从对象的lazy属性为proxy。在查询从对象时,必须要满足三个条件才能实现懒加载:
(1)从对象的映射文件中一对一映射的lazy属性不能设置成false;
(2)从对象的映射文件中一对一映射的constrained属性要设置成true;
(3)从对象的映射文件中一对一映射的fetch属性要设置成select。
第一条是设置是否采用懒加载,设置成false当然就不能实现懒加载了,可以设置成proxy和no-proxy两种;constrained属性设置成true是为了建立从对象表主键与主对象主键的外键关系的。如果这个属性设置成false,那么数据库里就不能保证主对象表里一定有一条记录与从对象表里的记录相对应,Hibernate也就不知道从对象里的主对象属性是应该赋成null还是赋成一个代理对象,所以就只能把主对象的记录也查询一下才能确认,这样就无法应用懒加裁了,这也是查询主对象时无法应用懒加载的原因;fetch属性可以设置成select和join两种,select是指查询主对象是通过另一条select语句去查询。如果设置成join,也就是说在取从对象的时候会inner join一下主对象,如果是这样的话,Hibernate就会直接把主对象信息取出来,自然也不需要懒加载了。
2. 一对多映射懒加载
一对多映射时分两种情况,一是查询一对象时的懒加载;二是查询多对象时的懒加载。
先说查询多对象时的懒加载。不像一对一映射查询主对象,默认时查询一个多对象时Hibernate也是会采用懒加载的。<many-to-one>标签需要两个属性设置,一是lazy不能设置成false;二是fetch不能设置为join。道理与前面一样。而这两个属性的默认值lazy是proxy、fetch是select,所以默认是进行懒加载的。
查询一对象时,默认也是懒加载的。这回设置属性应该是在集合标签里,而不是<one-to-many>标签里。并且lazy的值可以设置成true、false和extra三种,而不是之前的false、proxy和no-proxy三种。extra一种比较聪明的懒加载策略,如果调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条适当的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据。若要应用懒加载,应该设置lazy属性为true或extra;并且fetch属性要设置成select。
3. 多对多映射懒加载
多对多映射的懒加载与一对多映射懒加载在集合标签上的设置是相似的,lazy属性也有true、false和extra三个选项。
对象属性的懒加载
Hibernate还支持对象属性的懒加载。应用的情况比较少,而且应该在设计上避免出现这种情况