延迟加载(lazy load)又称为懒加载,延迟加载的机制是为了避免一些无谓性能的开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作
如何配置延时加载呢?
在Hibernate中通过对.hbm的lazy属性来赋值,不同位置出现lazy的作用和取值也是不同的,下面我们来分别介绍
一.Class标签中的lazy
我们可以看到class标签中的lazy有两个取值,分别为true和false,当lazy值为默认值true时,它是延迟加载的,当lazy值为false时,是立即加载的
我们来做例子实验一下
/* * 部门实体类 */ public class Dept { //不问标号 private Integer deptNo; private String deptName; //关联一个员工集合 private Set<Emp> sets=new HashSet<Emp>(); public Set<Emp> getSets() { return sets; } public void setSets(Set<Emp> sets) { this.sets = sets; } public Integer getDeptNo() { return deptNo; } public void setDeptNo(Integer deptNo) { this.deptNo = deptNo; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
<!--Dept.hbm.xml-->
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.a.entity"> <class name="Dept" table="Dept" lazy="true"> <id name="deptNo"> <generator class="sequence"> <param name="sequence">SEQ_Student</param> </generator> </id> <property name="deptName"></property> <set name="sets" cascade="save-update"> <key column="deptNo"></key> <!-- 多的一方的外建 --> <one-to-many class="Emp" /> </set> </class> </hibernate-mapping>
//测试端代码 @Test public void toTest() { Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); Dept dept=(Dept)session.load(Dept.class, 1); System.out.println(dept.getDeptNo()); System.out.println("================================"); tx.commit(); HibernateUtil.CloseSession(); }
这里注意,session.get()的方法不支持延时加载他会忽略掉类级别的lazy属性,当lazy为true的时候运行结果如下所示
那么,把lazy改为false时,其他代码都不变,运行结果如下所示
我们可以看到两种取值的区别,当lazy属性值为true时Hibernate并不会一次性加载出所有属性值,只有当程序需要时才去加载从而减少了和数据库交互的负担,提升了程序的性能,这也是延迟加载出现的目的!
二.Set元素中的lazy属性
如果对象中存在其他实体的集合则需要在hbm文件中配置set元素来进行表间的映射,而在set元素中也可以添加lazy强延时加载。
set元素中lazy有三个值,false(非延时加载),true(延时加载),extra(加强延时加载)
同样我们用上面的例子做测试
/* * 部门实体类 */ public class Dept { //不问标号 private Integer deptNo; private String deptName; //关联一个员工集合 private Set<Emp> sets=new HashSet<Emp>(); public Set<Emp> getSets() { return sets; } public void setSets(Set<Emp> sets) { this.sets = sets; } public Integer getDeptNo() { return deptNo; } public void setDeptNo(Integer deptNo) { this.deptNo = deptNo; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.a.entity"> <class name="Dept" table="Dept"> <id name="deptNo"> <generator class="sequence"> <param name="sequence">SEQ_Student</param> </generator> </id> <property name="deptName"></property> <set name="sets" cascade="save-update" lazy="true"> <key column="deptNo"></key> <!-- 多的一方的外建 --> <one-to-many class="Emp" /> </set> </class> </hibernate-mapping>
这里我们只比较true和extra的区别
@Test public void toTest() { Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); Dept dept=(Dept)session.load(Dept.class, 1); System.out.println(dept.getSets().size()); System.out.println("================================"); for (Emp item : dept.getSets()) { System.out.println(item.getEmpName()); } tx.commit(); HibernateUtil.CloseSession(); }
当lazy为true时,运行结果如下
当lazy为extra时,运行结果如下