您的位置:首页 > 其它

hibernate抓取策略

2013-10-21 00:21 176 查看
班级和学生是一对多关联:

班级表:



学生表:



Student.hbm.xml

<!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.xxc.domain.Student">
<id name="sid" type="long">
<column name="sid"></column>
<generator class="increment"></generator>
</id>
<property name="sname" type="string" length="20" column="sname"/>

<many-to-one name="clazz" column="cid" cascade="all"/>
</class>
</hibernate-mapping>


Class.hbm.xml

<!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.xxc.domain.Clazz">
<id name="cid" type="long">
<column name="cid" length="5"/>
<generator class="increment"/>
</id>
<property name="cname" type="string" length="20"/>

<!-- fetch抓取策略:select join subselect-->
<set name="stus" inverse="false" cascade="all" fetch="subselect">
<key column="cid"></key>
<one-to-many class="com.xxc.domain.Student"/>
</set>
</class>
</hibernate-mapping>


需求:查询出所有班级(4个班级)的所有学生信息

public void testLoad(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Query query = session.createQuery("from Clazz where cid in(1,2,3,4)");
List<Clazz> list_clzz = query.list();
for(Clazz clzz : list_clzz){
Set<Student> stus = clzz.getStus();
for(Student stu : stus){
//System.out.println(stu.getSname());
}
}

transaction.commit();
session.close();
}


1.如果Class.hbm.xml的set标签的fetch="select"(即默认情况)那么一共会发出4+1条sql语句

--1.这一条sql语句是查询所有班级引起的,from Clazz where cid in(1,2,3,4)这句hql引起的
Hibernate:
select
clazz0_.cid as cid0_,
clazz0_.cname as cname0_
from
Clazz clazz0_
where
clazz0_.cid in (
1 , 2 , 3 , 4
)
--2.以下4条sql语句是查询4个班级各自的学生集合引起的
Hibernate:
select
stus0_.cid as cid0_1_,
stus0_.sid as sid1_,
stus0_.sid as sid1_0_,
stus0_.sname as sname1_0_,
stus0_.cid as cid1_0_
from
Student stus0_
where
stus0_.cid=?
Hibernate:
select
stus0_.cid as cid0_1_,
stus0_.sid as sid1_,
stus0_.sid as sid1_0_,
stus0_.sname as sname1_0_,
stus0_.cid as cid1_0_
from
Student stus0_
where
stus0_.cid=?
Hibernate:
select
stus0_.cid as cid0_1_,
stus0_.sid as sid1_,
stus0_.sid as sid1_0_,
stus0_.sname as sname1_0_,
stus0_.cid as cid1_0_
from
Student stus0_
where
stus0_.cid=?
Hibernate:
select
stus0_.cid as cid0_1_,
stus0_.sid as sid1_,
stus0_.sid as sid1_0_,
stus0_.sname as sname1_0_,
stus0_.cid as cid1_0_
from
Student stus0_
where
stus0_.cid=?


2.如果Class.hbm.xml的set标签的fetch="subSelect",子查询,那么一共只发出2条sql语句

--1.这一条sql语句是查询所有班级引起的,from Clazz where cid in(1,2,3,4)这句hql引起的
Hibernate:
select
clazz0_.cid as cid0_,
clazz0_.cname as cname0_
from
Clazz clazz0_
where
clazz0_.cid in (
1 , 2 , 3 , 4
)
--2.由于配置了fetch="subselect"属性,在查询学生的时候,就按照学生的cid in(1,2,3,4)的子查询形式进行查询
Hibernate:
select
stus0_.cid as cid0_1_,
stus0_.sid as sid1_,
stus0_.sid as sid1_0_,
stus0_.sname as sname1_0_,
stus0_.cid as cid1_0_
from
Student stus0_
where
stus0_.cid in (
select
clazz0_.cid
from
Clazz clazz0_
where
clazz0_.cid in (
1 , 2 , 3 , 4
)
)


3.如果Class.hbm.xml的set标签的fetch="join"(左外连接),因为子查询可以满足要求查询出数据,所以生成的sql语句是和上面fetch="select"的一样,最差的查询效率

public void testLoad(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Clazz clazz = (Clazz) session.get(Clazz.class, 1L);//查询班级的时候,会使用左外连接查询学生

transaction.commit();
session.close();
}


Hibernate:
select
clazz0_.cid as cid0_1_,
clazz0_.cname as cname0_1_,
stus1_.cid as cid0_3_,
stus1_.sid as sid3_,
stus1_.sid as sid1_0_,
stus1_.sname as sname1_0_,
stus1_.cid as cid1_0_
from
Clazz clazz0_
left outer join
Student stus1_
on clazz0_.cid=stus1_.cid
where
clazz0_.cid=?


结论:



      
      
      
      
      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: