Hibernate延迟加载Lazy

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate延迟加载Lazy相关的知识,希望对你有一定的参考价值。

Hibernate延迟加载Lazy

延迟加载(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时,运行结果如下

技术分享

 

以上是关于Hibernate延迟加载Lazy的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate延迟加载Lazy

Hibernate的延迟加载 ,懒加载,lazy

Hibernate Lazy属性

八 Hibernate延迟加载&抓取策略(优化)

使用 FetchType.LAZY 防止 JPA/Hibernate 中的延迟加载(尤其是在使用 @Transactional 时)?

关于延迟加载(lazy)和强制加载(Hibernate.initialize(Object proxy) )