hibernate 中的lazy策略

hibernate 中的lazy策略


lazy策略可以用在: 
* <class>标签上:可以取值true/false 
* <property>标签上,可以取值true/false,这个特性需要类增强 
* <set>/<list>等集合上,可以取值为true/false/extra 
* <one-to-one>/<many-to-one>等标签上,可以取值false/proxy/no-proxy 

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

重要的概念: 
1、lazy的概念,指在需要的时候才发出sql 
2、lazy策略只是在session打开期间才是有效的 

注意: 
Hibernate类级别的lazy加载策略:可以控制什么时候加载这些普通对象属性 

测试单元的使用: 
请先运行初时化程序InitData,在执行每个单元测试 


Hibernate集合属性的懒加载策略: 

在集合属性上,可以配置懒加载策略,取值为:true/false/extra 

true:默认取值,它的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其 
     集合元素的数据 
false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据 
extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据 


Hibernate单端关联懒加载策略:即在<one-to-one>/<many-to-one>标签上可以配置 
懒加载策略。 

可以取值为:false/proxy/no-proxy 
false:取消懒加载策略,即在加载对象的同时,发出查询语句,加载其关联对象 
proxy:这是hibernate对单端关联的默认懒加载策略,即只有在调用到其关联对象的方法的时候 
      才真正发出查询语句查询其对象数据,其关联对象是代理类 
no-proxy:这种懒加载特性需要对类进行增强,使用no-proxy,其关联对象不是代理类 

注意:在class标签上配置的lazy属性不会影响到关联对象!!! 
<class name="com.bjsxt.hibernate.Classes" table="t_classes" lazy=  *"false">  这个实验证明class上的lazy属性影响的是普通属性,设为false,对普通属性为立刻发出sql语句,  *而对于集合等非普通属性则不会发出sql,即不支持


Java代码 
  1. <hibernate-mapping>  
  2.     <class name="com.bjsxt.hibernate.Group" table="t_group">  
  3.         <id name="id">  
  4.             <generator class="native"/>  
  5.         </id>  
  6.         <property name="name"/>  
  7.     </class>  
  8. </hibernate-mapping>    


Java代码 
  1. package com.bjsxt.hibernate;  
  2. import org.hibernate.Session;  
  3.   
  4. import com.bjsxt.hibernate.Group;  
  5. import com.bjsxt.hibernate.HibernateUtils;  
  6.   
  7.   
  8. public class InitData {  
  9.   
  10.     public static void main(String[] args) {  
  11.         Session session = null;  
  12.         try {  
  13.             session = HibernateUtils.getSession();  
  14.             session.beginTransaction();  
  15.             Group group = new Group();  
  16.             group.setName("java开发组");  
  17.             session.save(group);  
  18.             session.getTransaction().commit();  
  19.         }catch(Exception e) {  
  20.             e.printStackTrace();  
  21.             session.getTransaction().rollback();  
  22.         }finally {  
  23.             HibernateUtils.closeSession(session);  
  24.         }     
  25.     }  
  26.   
  27. }  

Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import org.hibernate.Session;  
  4.   
  5. import junit.framework.TestCase;  
  6.   
  7. /** 
  8.  * 运行本单元测试的前提条件: 
  9.  * 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性) 
  10.  *  
  11.  * @author Administrator 
  12.  * 
  13.  */  
  14. public class ClassLazyTest extends TestCase {  
  15.   
  16.     public void testLoadGroup1() {  
  17.         Session session = null;  
  18.         try {  
  19.             session = HibernateUtils.getSession();  
  20.               
  21.             //不会发出查询sql  ,注意get是不支持lazy的
  22.             Group group = (Group)session.load(Group.class1);  
  23.               
  24.             //不会发出查询sql  直接从上面load方法中取出id=1,故不发出sql
  25.             System.out.println("group id=" + group.getId());  
  26.               
  27.             //发出查询sql,加载数据到Group ,因为要执行取name操作,故发出sql 
  28.             System.out.println("group name=" + group.getName());  
  29.               
  30.             //不会发出查询sql  
  31.             System.out.println("group name=" + group.getName());  
  32.         }catch(Exception e) {  
  33.             e.printStackTrace();  
  34.         }finally {  
  35.             HibernateUtils.closeSession(session);  
  36.         }     
  37.     }  
  38.   
  39.     public void testLoadGroup2() {  
  40.         Session session = null;  
  41.         Group group = null;  
  42.         try {  
  43.             session = HibernateUtils.getSession();  
  44.               
  45.             //不会发出查询sql  
  46.             group = (Group)session.load(Group.class1);  
  47.               
  48.         }catch(Exception e) {  
  49.             e.printStackTrace();  
  50.         }finally {  
  51.             HibernateUtils.closeSession(session);  
  52.         }  
  53.         //不能正常输出,抛出了 LazyInitializationException,因为session已经关闭了  
  54.         //注意:Hibernate支持Lazy策略,只有session打开状态才有效       
  55.         System.out.println("group name=" + group.getName());  
  56.           
  57.     }  
  58.       
  59.       
  60. }  




--------------------------------------------------------------------- 
集合类测试 

Java代码 
  1. <hibernate-mapping>  
  2.     <class name="com.bjsxt.hibernate.Classes" table="t_classes">  
  3.         <id name="id">  
  4.             <generator class="native"/>  
  5.         </id>  
  6.         <property name="name"/>  
  7.         <!--   
  8.             <set name="students" cascade="all" order-by="id">  
  9.          -->  
  10.          <set name="students" lazy="extra">  
  11.             <key column="classid"/>  
  12.             <one-to-many class="com.bjsxt.hibernate.Student"/>  
  13.         </set>  
  14.     </class>  
  15. </hibernate-mapping>  
  16.   
  17. <hibernate-mapping>  
  18.     <class name="com.bjsxt.hibernate.Student" table="t_student">  
  19.         <id name="id">  
  20.             <generator class="native"/>  
  21.         </id>  
  22.         <property name="name"/>  
  23.     </class>  
  24. </hibernate-mapping>  


Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Set;  
  5.   
  6. import org.hibernate.Session;  
  7.   
  8. import junit.framework.TestCase;  
  9.   
  10. /** 
  11.  * 保持lazy的默认值 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class CollectionLazyTest1 extends TestCase {  
  16.       
  17.     public void testLoadClasses1() {  
  18.         Session session = null;  
  19.         try {  
  20.             session = HibernateUtils.getSession();  
  21.               
  22.             //不会发出查询sql  
  23.             Classes classes = (Classes)session.load(Classes.class1);  
  24.               
  25.             //会发出一条查询sql,加载数据到classes  
  26.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");  
  27.               
  28.             //不会发出查询sql  
  29.             Set students = classes.getStudents();  
  30.               
  31.             //会发出一条查询sql,加载数据到Students  
  32.             for (Iterator iter = students.iterator(); iter.hasNext();) {  
  33.                 Student student = (Student)iter.next();  
  34.                 System.out.println(student.getName());  
  35.             }  
  36.         }catch(Exception e) {  
  37.             e.printStackTrace();  
  38.         }finally {  
  39.             HibernateUtils.closeSession(session);  
  40.         }     
  41.     }  
  42.       
  43.     public void testLoadClasses2() {  
  44.         Session session = null;  
  45.         try {  
  46.             session = HibernateUtils.getSession();  
  47.               
  48.             //不会发出查询sql  
  49.             Classes classes = (Classes)session.load(Classes.class1);  
  50.               
  51.             //会发出一条查询sql,加载数据到classes  
  52.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");  
  53.   
  54.             //不会发出查询sql   
  55.             Set students = classes.getStudents();  
  56.               
  57.             //会发出一条查询sql,加载全部的数据到Students  
  58.             System.out.println(students.size());  
  59.               
  60.         }catch(Exception e) {  
  61.             e.printStackTrace();  
  62.         }finally {  
  63.             HibernateUtils.closeSession(session);  
  64.         }     
  65.     }  
  66.       
  67. }  


Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Set;  
  5.   
  6. import org.hibernate.Session;  
  7.   
  8. import junit.framework.TestCase;  
  9.   
  10. /** 
  11.  * 设置集合上的lazy=false 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class CollectionLazyTest2 extends TestCase {  
  16.       
  17.     public void testLoadClasses1() {  
  18.         Session session = null;  
  19.         try {  
  20.             session = HibernateUtils.getSession();  
  21.               
  22.             //不会发出查询sql  
  23.             Classes classes = (Classes)session.load(Classes.class1);  
  24.               
  25.             //会发出两条查询sql,加载数据到classes和Students中  
  26.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");  
  27.               
  28.             //不会发出查询sql  
  29.             Set students = classes.getStudents();  
  30.               
  31.             //不会发出查询sql  
  32.             for (Iterator iter = students.iterator(); iter.hasNext();) {  
  33.                 Student student = (Student)iter.next();  
  34.                 System.out.println(student.getName());  
  35.             }  
  36.         }catch(Exception e) {  
  37.             e.printStackTrace();  
  38.         }finally {  
  39.             HibernateUtils.closeSession(session);  
  40.         }     
  41.     }  
  42.       
  43.     public void testLoadClasses2() {  
  44.         Session session = null;  
  45.         try {  
  46.             session = HibernateUtils.getSession();  
  47.               
  48.             //不会发出查询sql  
  49.             Classes classes = (Classes)session.load(Classes.class1);  
  50.               
  51.             //会发出两条查询sql,加载数据到classes和Students中  
  52.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");  
  53.   
  54.             //不会发出查询sql   
  55.             Set students = classes.getStudents();  
  56.               
  57.             //不会发出查询sql   
  58.             System.out.println(students.size());  
  59.               
  60.         }catch(Exception e) {  
  61.             e.printStackTrace();  
  62.         }finally {  
  63.             HibernateUtils.closeSession(session);  
  64.         }     
  65.     }  
  66.       
  67. }  

Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import java.util.Iterator;  
  4. import java.util.Set;  
  5.   
  6. import org.hibernate.Session;  
  7.   
  8. import junit.framework.TestCase;  
  9.   
  10. /** 
  11.  * 设置集合上的lazy=extra 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class CollectionLazyTest3 extends TestCase {  
  16.       
  17.     public void testLoadClasses1() {  
  18.         Session session = null;  
  19.         try {  
  20.             session = HibernateUtils.getSession();  
  21.               
  22.             //不会发出查询sql  
  23.             Classes classes = (Classes)session.load(Classes.class1);  
  24.               
  25.             //会发出一条查询sql,加载数据到classes  
  26.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");  
  27.               
  28.             //不会发出查询sql  
  29.             Set students = classes.getStudents();  
  30.               
  31.             //会发出一条查询sql,加载数据到students  
  32.             for (Iterator iter = students.iterator(); iter.hasNext();) {  
  33.                 Student student = (Student)iter.next();  
  34.                 System.out.println(student.getName());  
  35.             }  
  36.         }catch(Exception e) {  
  37.             e.printStackTrace();  
  38.         }finally {  
  39.             HibernateUtils.closeSession(session);  
  40.         }     
  41.     }  
  42.       
  43.     public void testLoadClasses2() {  
  44.         Session session = null;  
  45.         try {  
  46.             session = HibernateUtils.getSession();  
  47.               
  48.             //不会发出查询sql  
  49.             Classes classes = (Classes)session.load(Classes.class1);  
  50.               
  51.             //会发出一条查询sql,加载数据到classes  
  52.             System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");  
  53.   
  54.             //不会发出查询sql   
  55.             Set students = classes.getStudents();  
  56.   
  57.             //会发出一条较为智能的查询sql,如:  
  58.             //select count(id) from t_student where classid =?  
  59.             System.out.println(students.size());  
  60.               
  61.         }catch(Exception e) {  
  62.             e.printStackTrace();  
  63.         }finally {  
  64.             HibernateUtils.closeSession(session);  
  65.         }     
  66.     }  
  67.       
  68. }  

---------------------------------------------------------------- 

单端关联加载 



Java代码 
  1. <hibernate-mapping>  
  2.     <class name="com.bjsxt.hibernate.Group" table="t_group">  
  3.         <id name="id">  
  4.             <generator class="native"/>  
  5.         </id>  
  6.         <property name="name"/>  
  7.     </class>  
  8. </hibernate-mapping>  
  9.   
  10. <hibernate-mapping>  
  11.     <class name="com.bjsxt.hibernate.User" table="t_user" >  
  12.         <id name="id">  
  13.             <generator class="native"/>  
  14.         </id>  
  15.         <property name="name"/>  
  16.         <!--  
  17.         <many-to-one name="group" column="relatedGroup" />  
  18.          -->  
  19.           
  20.         <many-to-one name="group" column="relatedGroup"/>   
  21.     </class>  
  22. </hibernate-mapping>        


Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import org.hibernate.Session;  
  4.   
  5. import junit.framework.TestCase;  
  6.   
  7. /** 
  8.  * 所有lazy的属性默认 
  9.  * @author Administrator 
  10.  * 
  11.  */  
  12. public class SingleEndTest1 extends TestCase {  
  13.   
  14.     public void testLoadUser() {  
  15.         Session session = null;  
  16.         try {  
  17.             session = HibernateUtils.getSession();  
  18.               
  19.             //不会发出查询sql  
  20.             User user = (User)session.load(User.class2);  
  21.               
  22.             //会发出一条查询sql,转载数据到User  
  23.             System.out.println("user name=" + user.getName());  
  24.               
  25.             //不会发出查询sql  
  26.             Group group = user.getGroup();  
  27.               
  28.             //会发出一条查询sql,转载数据到Group  
  29.             System.out.println("related group=" + group.getName());  
  30.               
  31.         }catch(Exception e) {  
  32.             e.printStackTrace();  
  33.         }finally {  
  34.               
  35.         }  
  36.     }  
  37. }  


Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import org.hibernate.Session;  
  4.   
  5. import junit.framework.TestCase;  
  6.   
  7. /** 
  8.  * 将<class>标签中的lazy设置为false 
  9.  * @author Administrator 
  10.  * 
  11.  */  
  12. public class SingleEndTest2 extends TestCase {  
  13.   
  14.     public void testLoadUser() {  
  15.         Session session = null;  
  16.         try {  
  17.             session = HibernateUtils.getSession();  
  18.               
  19.             //会发出一条查询sql,转载数据到User  
  20.             User user = (User)session.load(User.class2);  
  21.               
  22.             //不会发出查询sql  
  23.             System.out.println("user name=" + user.getName());  
  24.               
  25.             //不会发出查询sql  
  26.             Group group = user.getGroup();  
  27.               
  28.             //会发出一条查询sql,转载数据到Group  
  29.             System.out.println("related group=" + group.getName());  
  30.               
  31.         }catch(Exception e) {  
  32.             e.printStackTrace();  
  33.         }finally {  
  34.               
  35.         }  
  36.     }  
  37. }  


Java代码 
  1. package com.bjsxt.hibernate;  
  2.   
  3. import org.hibernate.Session;  
  4.   
  5. import junit.framework.TestCase;  
  6.   
  7. /** 
  8.  * 保持<class>标签中的lazy默认设置 
  9.  * 将<many-to-one>标签中加入lazy=false 
  10.  * @author Administrator 
  11.  * 
  12.  */  
  13. public class SingleEndTest3 extends TestCase {  
  14.   
  15.     public void testLoadUser() {  
  16.         Session session = null;  
  17.         try {  
  18.             session = HibernateUtils.getSession();  
  19.               
  20.             //会发出一条查询sql,转载数据到User  
  21.             User user = (User)session.load(User.class2);  
  22.               
  23.             //不会发出查询sql  
  24.             System.out.println("user name=" + user.getName());  
  25.               
  26.             //不会发出查询sql  
  27.             Group group = user.getGroup();  
  28.               
  29.             //会发出一条查询sql,转载数据到Group  
  30.             System.out.println("related group=" + group.getName());  
  31.               
  32.         }catch(Exception e) {  
  33.             e.printStackTrace();  
  34.         }finally {  
  35.               
  36.         }  
  37.     }  
  38. }  


































posted @ 2009-06-05 11:13  刘阳  阅读(404)  评论(0)    收藏  举报