`
penghao122
  • 浏览: 364106 次
  • 性别: Icon_minigender_1
  • 来自: 广东珠海
社区版块
存档分类
最新评论

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属性不会影响到关联对象!!!



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



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

}



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





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

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



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


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

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

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

单端关联加载




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



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


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


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





分享到:
评论
4 楼 pengjunwu 2010-01-14  
明显有些地方有错误的结论。。不要误导人。。。
要发就专业 严谨点吧 哥们
3 楼 darkmagician 2008-12-08  
  
2 楼 yanganq 2008-11-13  
 
1 楼 fujianqiangbo 2008-10-10  

相关推荐

    hibernate学习资料大全

    以上只是压缩包中部分可能包含的知识点,实际学习资料可能包括教程文档、示例代码、实战项目等,通过深入学习和实践,开发者可以全面掌握Hibernate的精髓,并将其应用到实际开发中,提高开发效率,降低维护成本。...

    hibernate全套学习课件ppt

    【hibernate全套学习课件ppt】是一套全面讲解Hibernate技术的PPT教程,源自国内知名的计算机教育机构——新华电脑教育集团。Hibernate是Java开发领域中一个极为重要的对象关系映射(ORM)框架,它极大地简化了数据库...

    Hibernate3.3_学习笔记.doc.zip

    总之,《Hibernate3.3_学习笔记》这份文档全面覆盖了Hibernate3.3的核心知识点,从基础概念到高级用法,为开发者提供了详实的学习资料。通过深入学习,开发者不仅能熟练使用Hibernate,还能更好地理解和应对各种...

    hibernate最新学习手册

    本学习手册全面涵盖了Hibernate的最新知识点,旨在帮助程序员更好地理解和运用这一强大的工具。 一、Hibernate概述 Hibernate是Java平台上的一个开源ORM框架,它允许开发者将数据库操作转化为对Java对象的操作,...

    Hibernate—详细学习笔记

    总之,这份Hibernate学习笔记通过丰富的实例和详尽的解释,旨在帮助读者全面掌握Hibernate的使用,无论是初学者还是有经验的开发者,都能从中受益匪浅。通过学习和实践,读者不仅可以理解Hibernate的核心原理,还能...

    hibernate学习课件

    通过这个系列的学习课件,你将全面掌握Hibernate的基础知识和高级技巧,能够自如地在Java项目中应用Hibernate进行数据持久化操作。在实际开发过程中,结合最佳实践和持续学习,你将成为一名熟练的Hibernate开发者。

    Hibernate学习资料

    Hibernate的学习资料涵盖了从基础知识到高级特性的全面内容,对于想要深入学习Hibernate的开发者来说,这是一份非常宝贵的资源。通过系统地学习这些内容,开发者不仅可以掌握Hibernate的基本用法,还能深入了解其...

    Hibernate4.1.11中文手册

    《Hibernate4.1.11中文手册》是一个全面介绍Hibernate框架的资源集合,适用于初学者和有经验的开发人员。Hibernate是Java平台上的一个开源对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发人员可以更加...

    hibernate学习笔记

    此外,笔记可能还会涉及到Hibernate的延迟加载(Lazy Loading)和立即加载(Eager Loading),这两种策略可以帮助优化性能。延迟加载在需要时才加载关联的对象,而立即加载则会一次性加载所有关联数据。 总之,...

    传智播客_hibernate

    通过以上讲解,我们可以看到,传智播客的Hibernate教程覆盖了从基础到进阶的各个方面,为初学者提供了全面的学习资源。掌握Hibernate能够极大地提升Java开发中的数据库操作效率,是Java开发者必备的技能之一。通过...

    有关hibernate的论文

    Hibernate支持多种持久化策略,如懒加载(Lazy Loading)、立即加载(Eager Loading)和级联(Cascading)。懒加载可以推迟加载关联对象,直到真正需要时才从数据库获取,以优化性能;立即加载则会在加载主对象时...

    解决Lazy最有效的方法

    ### 二、Spring框架下的Lazy Loading策略 在给定的部分代码中,我们可以看到`&lt;load-on-startup&gt;`标签被设置为`1`,这意味着`ContextLoaderServlet`将在Web应用启动时被自动加载和初始化,而非采用懒加载策略。`...

    hibernate3.2 开发API+源码参考

    总之,这个压缩包提供了一个全面学习Hibernate 3.2的平台,无论你是初学者还是有经验的开发者,都能从中受益匪浅。通过深入研究API、源码和实践案例,你将能够更高效地利用Hibernate来构建数据驱动的应用程序。

    hibernate中文参考文档pdf

    这本参考手册全面覆盖了Hibernate 3.6.10的关键特性和用法,是Java开发者深入理解和应用Hibernate不可或缺的参考资料。通过阅读和实践,开发者可以掌握如何利用Hibernate简化数据访问层的开发,提升项目效率。

    hibernate5.0中文文档

    总的来说,《Hibernate 5.0 中文文档》是一份全面而实用的学习资料,无论是初学者还是经验丰富的开发者,都能从中受益,提升自己的Hibernate技能。通过深入学习这份文档,开发者可以更好地驾驭Java世界的持久化,...

    hibernate-html-single

    这个文档通常包含了对Hibernate框架全面而详尽的介绍,涵盖了从基本概念到高级特性的各个方面,是Hibernate开发者的必备参考资料。 Hibernate是一个开源的对象关系映射(ORM)框架,它为Java应用程序提供了在关系...

    Hibernate学习包

    总之,“Hibernate学习包”是一个全面的学习资源,涵盖了Hibernate的基础到高级用法。无论你是初学者还是有经验的开发者,都能从中受益,提升你在Java ORM领域的技能。通过深入学习和实践,你将能够高效地管理Java...

    HIBERNATE官方参考手册

    12. **延迟加载(Lazy Loading)**:Hibernate的懒加载策略允许关联对象在真正需要时才加载,以减少数据库交互。 13. **级联操作(Cascading)**:设置级联属性后,对一个实体的操作会级联影响到与之关联的其他实体...

Global site tag (gtag.js) - Google Analytics