`

Hibernate抓取策略二

阅读更多

在Classes与Student一对多映射中,我们将Set里面的fetch属性设置为subselect来实现子查询。

如下示例

首先看一下set中fetch="select"即默认情况下:

生成数据类:

package com.bjsxt.hibernate;

import org.hibernate.Session;

public class InitData {

	public static void main(String[] args) {
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			for(int i=0; i<10; i++){
				Classes classes = new Classes();
				classes.setName("班级"+i);
				session.save(classes);
				for(int j=0; j<10; j++){
					Student student = new Student();
					student.setName("班级"+i+"的学生"+j);
					//在内存中建立由student指向classes的引用
					student.setClasses(classes);
					session.save(student);
				}
			}
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}

}

 

测试类:

package com.bjsxt.hibernate;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;

import junit.framework.TestCase;

public class FetchTest extends TestCase {

	public void testFetch1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Classes classes = (Classes)session.load(Classes.class, 1);
			System.out.println("班级:" + classes.getName());
			Set students = classes.getStudents();
			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 testFetch2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			List Classes = session.createQuery("select c from Classes c where c.id in(1, 2, 3)").list();
			for (Iterator iter = Classes.iterator(); iter.hasNext();) {
				Classes cls = (Classes)iter.next();
				System.out.println("班级:" + cls.getName());
				for (Iterator iter1 = cls.getStudents().iterator(); iter1.hasNext();) {
					Student student = (Student)iter1.next();
					System.out.println(student.getName());
				}
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
}

 

分别列出方法一与方法二的测试结果:

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?
班级:班级0
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid=?
班级0的学生8
班级0的学生1
班级0的学生7
班级0的学生5
班级0的学生3
班级0的学生4
班级0的学生0
班级0的学生6
班级0的学生9
班级0的学生2

 

Hibernate: select classes0_.id as id0_, classes0_.name as name0_ from t_classes classes0_ where classes0_.id in (1 , 2 , 3)
班级:班级0
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid=?
班级0的学生7
班级0的学生2
班级0的学生3
班级0的学生1
班级0的学生0
班级0的学生9
班级0的学生4
班级0的学生8
班级0的学生6
班级0的学生5
班级:班级1
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid=?
班级1的学生9
班级1的学生0
班级1的学生6
班级1的学生8
班级1的学生7
班级1的学生2
班级1的学生5
班级1的学生3
班级1的学生1
班级1的学生4
班级:班级2
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid=?
班级2的学生6
班级2的学生9
班级2的学生3
班级2的学生1
班级2的学生2
班级2的学生7
班级2的学生8
班级2的学生4
班级2的学生0
班级2的学生5

 

下面更改fetch="subselect"

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<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" inverse="true" fetch="subselect">
			<key column="classid"/>
			<one-to-many class="com.bjsxt.hibernate.Student"/>
		</set>
	</class>
</hibernate-mapping>

 

同样,将两个方法的测试结果列出如下:

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?
班级:班级0
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid=?
班级0的学生3
班级0的学生1
班级0的学生9
班级0的学生7
班级0的学生5
班级0的学生0
班级0的学生6
班级0的学生2
班级0的学生8
班级0的学生4

 

Hibernate: select classes0_.id as id0_, classes0_.name as name0_ from t_classes classes0_ where classes0_.id in (1 , 2 , 3)
班级:班级0
Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid in (select classes0_.id from t_classes classes0_ where classes0_.id in (1 , 2 , 3))
班级0的学生5
班级0的学生1
班级0的学生0
班级0的学生8
班级0的学生7
班级0的学生2
班级0的学生9
班级0的学生6
班级0的学生4
班级0的学生3
班级:班级1
班级1的学生5
班级1的学生1
班级1的学生0
班级1的学生7
班级1的学生4
班级1的学生9
班级1的学生8
班级1的学生3
班级1的学生6
班级1的学生2
班级:班级2
班级2的学生0
班级2的学生5
班级2的学生1
班级2的学生8
班级2的学生6
班级2的学生9
班级2的学生4
班级2的学生7
班级2的学生3
班级2的学生2

 

比较两次测试的结果我们发现,方法二的输出结果不同,当fetch="subselect"的时候,方法二进行了子查询

如:

Hibernate: select students0_.classid as classid0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.classid as classid1_0_ from t_student students0_ where students0_.classid in (select classes0_.id from t_classes classes0_ where classes0_.id in (1 , 2 , 3))

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics