hibernate抓取策略

班级和学生是一对多关联:

班级表:

学生表:


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=?





结论:



      
      
      
      
      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值