天天看點

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

<hibernate-mapping package="com.zd.model">

    <class name="classes" table="classes" >

            <generator class="native" />

        <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>

    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());

     }

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條查詢語句了。

若<set name="students" lazy="extra"> //和true差不多,隻是在寫set.size()時,發出selcet count的sql語句,比true好一些。

    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());

      student s = (student) it.next();

hibernate: select count(id) from student where class_id =?

3.<one-to-one><many-to-one>單端關聯上,可以取值:false/proxy/no-proxy,預設是proxy(代理),延遲加載作用

user.hbm.xml 多的一端

    <class name="user" table="user1" >

        <id name="id" column="user_id" type="java.lang.integer">

        <property name="name" length="50" type="java.lang.string" />

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

         //可不寫,預設是proxy

public void testget1(){

   user user = null;

    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.rollback();

若<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