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=?班级:班级0Hibernate: 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)班级:班级0Hibernate: 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班级:班级1Hibernate: 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班级:班级2Hibernate: 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 cascade="all" order-by="id"> --> <set name="students" inverse="true" fetch="subselect"><key column="classid"/><one-to-many name="code">Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?班级:班级0Hibernate: 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)班级:班级0Hibernate: 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))
?