Hibernate抓取策略一
抓取策略指多表关联查询的时候,Hibernate会发出多条sql进行查询,但如果设置了抓取策略,将多条SQL变成一条SQL执行,实际上就是使用join等关联查询。
?
如在一对多即示例Classes与Student的关联查询中:
代码:
public void testLoad(){Session session = null;try {session = HibernateUtil.getSession();session.beginTransaction();//从classes得到studentClasses cls = (Classes)session.load(Classes.class, 1);System.out.println(cls.getName());Set set = cls.getStudents();for (Iterator iterator = set.iterator(); iterator.hasNext();) {Student object = (Student) iterator.next();System.out.println(object.getName());}HibernateUtil.commit(session);} catch (Exception e) {HibernateUtil.roolback(session);}finally{HibernateUtil.close(session);}}?
可以看到上面要打印出classes.name和classes.student.name那么默认情况下输出的SQL是:
Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?classes1Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from t_student students0_ where students0_.class_id=?stu4stu2stu1stu0stu3
?
?
?
而我们可以使用抓取策略:
更改Classes.hbm.xml.在set中增加fetch属性
<hibernate-mapping package="com.lwf.hibernate.pojo"><class name="Classes" table="t_classes"><id name="id"><generator fetch="join"><key column="class_id"/><one-to-many name="code">Hibernate: select classes0_.id as id0_1_, classes0_.name as name0_1_, students1_.class_id as class3_0_3_, students1_.id as id3_, students1_.id as id1_0_, students1_.name as name1_0_, students1_.class_id as class3_1_0_ from t_classes classes0_ left outer join t_student students1_ on classes0_.id=students1_.class_id where classes0_.id=?classes1stu2stu4stu1stu3stu0
?
显然上面比较使用抓取策略后执行的SQL语句少了,性能也跟着提高了。。
上面我们是从Classes端得到Student所以在Classes.hbm.xml中的set里面加了fetch属性。
那么如果我们从Student端得到Classes要使用fetch怎么做呢?
测试方法:
public void testLoad1(){Session session = null;try {session = HibernateUtil.getSession();session.beginTransaction();Student s = (Student)session.load(Student.class, 1);System.out.println(s.getName());System.out.println(s.getClasses().getName());HibernateUtil.commit(session);} catch (Exception e) {HibernateUtil.roolback(session);}finally{HibernateUtil.close(session);}}?
默认情况下执行:发出两条SQL
Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.class_id as class3_1_0_ from t_student student0_ where student0_.id=?stu0Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?classes1
?而要执行抓取策略,更改Student.hbm.xml的many-to-one
<?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 package="com.lwf.hibernate.pojo"><class name="Student" table="t_student"><!-- <cache usage="read-only"/> --><id name="id"><generator column="class_id" fetch="join"></many-to-one></class></hibernate-mapping>
?
上面我们增加了fetch="join"属性
结果:
Hibernate: select student0_.id as id1_1_, student0_.name as name1_1_, student0_.class_id as class3_1_1_, classes1_.id as id0_0_, classes1_.name as name0_0_ from t_student student0_ left outer join t_classes classes1_ on student0_.class_id=classes1_.id where student0_.id=?stu0classes1
?
现在只执行一条SQL了。。。
?
需要提示的是其实默认情况下fetch="select"