读书人

Hibernate抓取计策一

发布时间: 2012-10-14 14:55:08 作者: rapoo

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"

读书人网 >软件架构设计

热点推荐