hibernate 全面学习【lazy策略 】

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

重要的概念: 
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属性不会影响到关联对象!!! 



Java代码 
<hibernate-mapping>
	<class name="com.bjsxt.hibernate.Group" table="t_group">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>	



Java代码 
package com.bjsxt.hibernate;
import org.hibernate.Session;

import com.bjsxt.hibernate.Group;
import com.bjsxt.hibernate.HibernateUtils;


public class InitData {

	public static void main(String[] args) {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Group group = new Group();
			group.setName("java开发组");
			session.save(group);
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}

}


Java代码 
  
package com.bjsxt.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 运行本单元测试的前提条件:
 * 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性)
 * 
 * @author Administrator
 *
 */
public class ClassLazyTest extends TestCase {

	public void testLoadGroup1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Group group = (Group)session.load(Group.class, 1);
			
			//不会发出查询sql
			System.out.println("group id=" + group.getId());
			
			//发出查询sql,加载数据到Group
			System.out.println("group name=" + group.getName());
			
			//不会发出查询sql
			System.out.println("group name=" + group.getName());
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}

	public void testLoadGroup2() {
		Session session = null;
		Group group = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			group = (Group)session.load(Group.class, 1);
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
		//不能正常输出,抛出了 LazyInitializationException,因为session已经关闭了
		//注意:Hibernate支持Lazy策略,只有session打开状态才有效		
		System.out.println("group name=" + group.getName());
		
	}
	
	
}





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

Java代码 
<hibernate-mapping>   
    <class name="com.bjsxt.hibernate.Classes" table="t_classes">   
        <id name="id">   
            <generator class="native"/>   
        </id>   
        <property name="name"/>   
        <!--    
            <set name="students" cascade="all" order-by="id">   
         -->   
         <set name="students" lazy="extra">   
            <key column="classid"/>   
            <one-to-many class="com.bjsxt.hibernate.Student"/>   
        </set>   
    </class>   
</hibernate-mapping>   
  
<hibernate-mapping>   
    <class name="com.bjsxt.hibernate.Student" table="t_student">   
        <id name="id">   
            <generator class="native"/>   
        </id>   
        <property name="name"/>   
    </class>   
</hibernate-mapping>  

Java代码 
package com.bjsxt.hibernate;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 保持lazy的默认值
 * @author Administrator
 *
 */
public class CollectionLazyTest1 extends TestCase {
	
	public void testLoadClasses1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出一条查询sql,加载数据到classes
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");
			
			//不会发出查询sql
			Set students = classes.getStudents();
			
			//会发出一条查询sql,加载数据到Students
			for (Iterator iter = students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
	public void testLoadClasses2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出一条查询sql,加载数据到classes
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");

			//不会发出查询sql	
			Set students = classes.getStudents();
			
			//会发出一条查询sql,加载全部的数据到Students
			System.out.println(students.size());
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
}


Java代码 


package com.bjsxt.hibernate;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 设置集合上的lazy=false
 * @author Administrator
 *
 */
public class CollectionLazyTest2 extends TestCase {
	
	public void testLoadClasses1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出两条查询sql,加载数据到classes和Students中
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");
			
			//不会发出查询sql
			Set students = classes.getStudents();
			
			//不会发出查询sql
			for (Iterator iter = students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
	public void testLoadClasses2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出两条查询sql,加载数据到classes和Students中
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");

			//不会发出查询sql	
			Set students = classes.getStudents();
			
			//不会发出查询sql	
			System.out.println(students.size());
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
}

Java代码 
package com.bjsxt.hibernate;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 设置集合上的lazy=extra
 * @author Administrator
 *
 */
public class CollectionLazyTest3 extends TestCase {
	
	public void testLoadClasses1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出一条查询sql,加载数据到classes
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生:");
			
			//不会发出查询sql
			Set students = classes.getStudents();
			
			//会发出一条查询sql,加载数据到students
			for (Iterator iter = students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
	public void testLoadClasses2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			Classes classes = (Classes)session.load(Classes.class, 1);
			
			//会发出一条查询sql,加载数据到classes
			System.out.println("班级:【" + classes.getName() + "】  拥有的学生总数:");

			//不会发出查询sql	
			Set students = classes.getStudents();

			//会发出一条较为智能的查询sql,如:
			//select count(id) from t_student where classid =?
			System.out.println(students.size());
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}	
	}
	
}

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

单端关联加载 



Java代码 
  
<hibernate-mapping>   
    <class name="com.bjsxt.hibernate.Group" table="t_group">   
        <id name="id">   
            <generator class="native"/>   
        </id>   
        <property name="name"/>   
    </class>   
</hibernate-mapping>   
  
<hibernate-mapping>   
    <class name="com.bjsxt.hibernate.User" table="t_user" >   
        <id name="id">   
            <generator class="native"/>   
        </id>   
        <property name="name"/>   
        <!--   
        <many-to-one name="group" column="relatedGroup" />   
         -->   
           
        <many-to-one name="group" column="relatedGroup"/>    
    </class>   
</hibernate-mapping>        


<hibernate-mapping>
	<class name="com.bjsxt.hibernate.Group" table="t_group">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>

<hibernate-mapping>
	<class name="com.bjsxt.hibernate.User" table="t_user" >
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<!--
		<many-to-one name="group" column="relatedGroup" />
		 -->
		
		<many-to-one name="group" column="relatedGroup"/> 
	</class>
</hibernate-mapping>		



Java代码 
package com.bjsxt.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 所有lazy的属性默认
 * @author Administrator
 *
 */
public class SingleEndTest1 extends TestCase {

	public void testLoadUser() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//不会发出查询sql
			User user = (User)session.load(User.class, 2);
			
			//会发出一条查询sql,转载数据到User
			System.out.println("user name=" + user.getName());
			
			//不会发出查询sql
			Group group = user.getGroup();
			
			//会发出一条查询sql,转载数据到Group
			System.out.println("related group=" + group.getName());
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			
		}
	}
}


Java代码 
package com.bjsxt.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

/**
 * 将<class>标签中的lazy设置为false
 * @author Administrator
 *
 */
public class SingleEndTest2 extends TestCase {

	public void testLoadUser() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			//会发出一条查询sql,转载数据到User
			User user = (User)session.load(User.class, 2);
			
			//不会发出查询sql
			System.out.println("user name=" + user.getName());
			
			//不会发出查询sql
			Group group = user.getGroup();
			
			//会发出一条查询sql,转载数据到Group
			System.out.println("related group=" + group.getName());
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			
		}
	}
}

Java代码 
package com.bjsxt.hibernate;   
  
import org.hibernate.Session;   
  
import junit.framework.TestCase;   
  
/**  
 * 保持<class>标签中的lazy默认设置  
 * 将<many-to-one>标签中加入lazy=false  
 * @author Administrator  
 *  
 */  
public class SingleEndTest3 extends TestCase {   
  
    public void testLoadUser() {   
        Session session = null;   
        try {   
            session = HibernateUtils.getSession();   
               
            //会发出一条查询sql,转载数据到User   
            User user = (User)session.load(User.class, 2);   
               
            //不会发出查询sql   
            System.out.println("user name=" + user.getName());   
               
            //不会发出查询sql   
            Group group = user.getGroup();   
               
            //会发出一条查询sql,转载数据到Group   
            System.out.println("related group=" + group.getName());   
               
        }catch(Exception e) {   
            e.printStackTrace();   
        }finally {   
               
        }   
    }   
}

 摘自:http://penghao122.javaeye.com/blog/211598

转载于:https://my.oschina.net/zlp5201/blog/404148

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值