hibernate lazy——延迟加载

简介:
 hibernate lazy策略可以使用在:
* <class>标签上,可以取值:true/false ,在hibernate3以上版本,默认是true
* <property>标签上,可以取值:true/false 需要类增强工具
* <set><list>标签上,可以取值:true/false/extra
* <one-to-one><many-to-one>单端关联上,可以取值:false/proxy/no-proxy

lazy概念:只有真正使用该对象时,才会创建,对于hibernate而言,正真使用的时候才会发出sql

hibernate支持lazy策略只有在session打开状态下有效



1 <class>标签上:


group.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
    <class name="Group" table="group5" lazy="true" > //lazy,默认true,可不写
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />        
        </id>
        <property name="name" column="name" length="50" type="java.lang.String" />
    </class>
</hibernate-mapping>

测试用例:

public class LazyTest extends TestCase

{

public void testLoad1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();

    //还没发出sql,lazy起延迟作用,若lazy=false,则发出sql

    Group g2 = (Group) session.load(Group.class, 1);
    Group g3 = (Group) session.get(Group.class, 1);   //不支持lazy
    System.out.println("group.id=" + g2.getId());     //还没发出sql,
    System.out.println("group.name=" + g2.getName()); //发出sql
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
   // System.out.println("group.name=" + g2.getName());
   // hibernate支持lazy策略只有在session打开状态下有效,所以此出Exception
}

}

<class>标签上的lazy特性只对普通属性起作用

<class>标签上的lazy不会影响到单端关联上的lazy特性




2.<set><list>标签上,可以取值:true/false/extra,默认是true

Classes.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zd.model">
    <class name="Classes" table="classes" >
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />
        </id>
        <property name="name" column="name" type="java.lang.String" />
        <set name="students" lazy="true"> //可不配lazy,因默认是true
            <key column="class_id" />
            <one-to-many class="com.zd.model.Student" />
        </set>
    </class>

</hibernate-mapping>

测试用例:

public void testLoad1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Classes c = (Classes) session.load(Classes.class, new Integer(2));  //没有sql
    System.out.println("Class.name=" + c.getName());                    //发出一条sql,但不查 set
    Set stuSet = c.getStudents();                                   //没有发出查询sql,不是统计sql
    //System.out.println(stuSet.size());//发出查询sqlsql
    if(stuSet != null && !stuSet.isEmpty()){
     //发出查询sqlsql
     for(Iterator it = stuSet.iterator(); it.hasNext();){
      Student s = (Student) it.next();//若没有.size(),isEmpty(),就在这边发出sql
      System.out.println("student.name=" + s.getName());
     }
    }
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes classes0_ where classes0_.id=?
Class.name=Java Class
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
2
student.name=z3
student.name=l4

若<set name="students" lazy="false"> //不延迟加载, 马上加载

则在

System.out.println("Class.name=" + c.getName());// 就发出2条查询语句了。

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes classes0_ where classes0_.id=?
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
Class.name=Java Class
student.name=l4
student.name=z3

若<set name="students" lazy="extra"> //和true差不多,只是在写set.size()时,发出selcet count的sql语句,比true好一些。

测试用例:

public void testLoad1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Classes c = (Classes) session.load(Classes.class, new Integer(2));
    System.out.println("Class.name=" + c.getName());
    Set stuSet = c.getStudents();
    System.out.println(stuSet.size());
    if(stuSet != null && !stuSet.isEmpty()){
     for(Iterator it = stuSet.iterator(); it.hasNext();){
      Student s = (Student) it.next();
      System.out.println("student.name=" + s.getName());
     }
    }
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
     ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes classes0_ where classes0_.id=?
Class.name=Java Class
Hibernate: select count(id) from student where class_id =?
2
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
student.name=z3
student.name=l4




3.<one-to-one><many-to-one>单端关联上,可以取值:false/proxy/no-proxy,默认是proxy(代理),延迟加载作用

User.hbm.xml 多的一端

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
    <class name="User" table="user1" >
        <id name="id" column="user_id" type="java.lang.Integer">
            <generator class="native" />
        </id>
        <property name="name" length="50" type="java.lang.String" />
        <many-to-one name="group" column="group_id" lazy="proxy"></many-to-one>
         //可不写,默认是proxy
    </class>

</hibernate-mapping>

测试用例:

public void testGet1(){
   Session session = null;
   Transaction ta = null;
   User user = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    user = (User)session.load(User.class, new Integer(3)); //无sql
    System.out.println("user.name=" + user.getName()); //有一条sql
    Group group = user.getGroup();//无sql
    System.out.println("group.name=" + group.getName());//有一条sql
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    ta.rollback();
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }
 
}

若<many-to-one name="group" column="group_id" lazy="false"></many-to-one>

不延迟加载,立即加载,

System.out.println("user.name=" + user.getName()); //发出2条sql语句


原帖地址: http://apps.hi.baidu.com/share/detail/38568475

目录
相关文章
|
3月前
|
Java 数据库连接 数据库
|
Java 数据库连接 Spring
Hibernate延迟加载问题
  Hibernate延迟加载是项目中非常常用的技术。通过使用Hibernate延迟加载机制可以在加载数据是不必加载全部数据,而是只加载我们需要的那部分,其余部分在需要使用时才从数据库装载,以此来减少数据量提高系统性能。
1060 0
|
SQL 缓存 Java
Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)
  假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下:   假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: 1 Session session=HibernateUtil.
1273 0
|
Java 数据库连接 数据库
Hibernate的延迟加载
 ----------------------------------------------  一 ------------------------------------------- 转自:http://blog.csdn.net/java958199586/article/details/7069901 hibernate延迟加载(懒加载)详解 一.什么是懒加载?他的作
1257 0
|
SQL Java 数据库连接
hibernate 延迟加载
Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载。Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hibernate 的运行性能。
784 0
|
Java Spring 数据库连接
hibernate 延迟加载的错误 failed to lazily initialize a collection of role
这个问题一般出现在一对多的情况下,解决的方法有两种1、设置lazy=false如果是用annotation,则配置如下@OneToMany(   targetEntity = CourseAuthorizationItem.class,   cascade = {CascadeType.PERSIST, CascadeType.MERGE},   mappedBy = "course",
2260 0
|
SQL Java 数据库连接
Hibernate延迟加载
1、类级别的延迟加载  1、   是通过session.load方法实现的    在映射文件中:     &lt;class name="cn.itcast.hibernate717.lazy.Customer" table="customer" catalog="test" lazy="true"&gt;      lazy表示延迟加载    2、   当映射文件中,class元素的属性la
1068 0
|
Java 数据库连接 数据格式
Hibernate延迟加载问题
Hibernate的映射配置单如下: DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.
853 0