hibernate数据检索策略

hibernate框架提供的检索策略有立即检索延迟检索预先检索批量检索

帖子(Topic)与回复(Reply)之间是一对多的关联关系。

Topic类:

public class Topic {
	private int id;
	private String title;
	private Date createDate;
	private String content;
	private Set<Reply> replys = new HashSet<Reply>();
        //省略getter、setter方法
}
Reply类:

public class Reply implements Serializable{
	private int id;
	private Date createDate;
	private String content;
	private Topic topic;
        //省略getter、setter方法
}

一、立即检索策略:

        立即检索指的是在加载一个对象时不仅立即加载该对象,并且还会立即加载与该对象相关联的其他对象。例如:查询一个帖子信息时,会将该帖子所关联的所有回复查询出来。

(1)Annotation:

使用fetch=FetchType.EAGER

@Entity
public class Topic {
	private int id;
	private String title;
	private Date createDate;
	private String content;
	private Set<Reply> replys = new HashSet<Reply>();
	
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}

	@OneToMany(mappedBy="topic",fetch=FetchType.EAGER)  //一对多默认fetch = FetchType.LAZY
	public Set<Reply> getReplys() {
		return replys;
	}
      //省略getter、setter方法
}
(2)xml:

需要将<class>元素和<set>元素内的lazy属性值都设为false。

 <class name="Topic" table="Topic" lazy="false">
  <id name="id">
   <column name="id"/>
   <generator class="native"/>
  </id>
  <property  name="title"/>
  <property  name="createDate"/>
  <property  name="content"/>
  
  <set  name="replys" lazy="false">
   <key column="topicid"/>
   <one-to-many class="com.SearchStrategy.Immediately.Reply"/>
  </set>
 </class>

测试语句:

session.createQuery("from Topic").list();

hibernate发出的SQL语句:

//Annotation配置:
Hibernate: 
    select
        topic0_.id as id0_,
        topic0_.content as content0_,
        topic0_.createDate as createDate0_,
        topic0_.title as title0_ 
    from
        Topic topic0_
Hibernate: 
    select
        replys0_.topicId as topicId0_1_,
        replys0_.id as id1_1_,
        replys0_.id as id1_0_,
        replys0_.content as content1_0_,
        replys0_.createDate as createDate1_0_,
        replys0_.topicId as topicId1_0_ 
    from
        Reply replys0_ 
    where
        replys0_.topicId=?
Hibernate: 
    ....  
   //省略N条reply的SQL查询语句,N对应于Topic表的条数

//xml配置:
Hibernate: 
    select
        topic0_.id as id0_,
        topic0_.title as title0_,
        topic0_.createDate as createDate0_,
        topic0_.content as content0_ 
    from
        Topic topic0_
Hibernate: 
    select
        replys0_.topicid as topicid0_2_,
        replys0_.id as id1_2_,
        replys0_.id as id1_1_,
        replys0_.createDate as createDate1_1_,
        replys0_.content as content1_1_,
        replys0_.topicId as topicId1_1_,
        topic1_.id as id0_0_,
        topic1_.title as title0_0_,
        topic1_.createDate as createDate0_0_,
        topic1_.content as content0_0_ 
    from
        Reply replys0_ 
    left outer join
        Topic topic1_ 
            on replys0_.topicId=topic1_.id 
    where
        replys0_.topicid=?
Hibernate: 
    ....  
   //省略N条reply的SQL查询语句,N对应于Topic表的条数

二、延迟加载策略

        延迟加载是指对象在使用到时才会进行加载。

(1)Annotation:

@Entity
public class Topic {
	private int id;
	private String title;
	private Date createDate;
	private String content;
	private Set<Reply> replys = new HashSet<Reply>();
	
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}

	@OneToMany(mappedBy="topic",fetch=FetchType.LAZY)  //一对多默认fetch = FetchType.LAZY
	public Set<Reply> getReplys() {
		return replys;
	}
      //省略getter、setter方法
}

(2)xml:

需要将<class>元素和<set>元素内的lazy属性值都设为true。

 <class name="Topic" table="Topic" lazy="true">
  <id name="id">
   <column name="id"/>
   <generator class="native"/>
  </id>
  <property  name="title"/>
  <property  name="createDate"/>
  <property  name="content"/>
  
  <set  name="replys" lazy="true">
   <key column="topicid"/>
   <one-to-many class="com.SearchStrategy.Delay.Reply"/>
  </set>
 </class>

测试语句:

session.createQuery("from Topic").list();

hibernate发出的SQL语句:

Hibernate: 
    select
        topic0_.id as id0_0_,
        topic0_.content as content0_0_,
        topic0_.createDate as createDate0_0_,
        topic0_.title as title0_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?

三、预先加载策略

预先加载指的是一种通过左外连接来获得对象关联实例或者集合的检索方法,主要用于关联级别的查询。

(1)xml:

将<set>元素内的fetch属性值都设为join。

 <class name="Topic" table="Topic" lazy="false">
  <id name="id">
   <column name="id"/>
   <generator class="native"/>
  </id>
  <property  name="title"/>
  <property  name="createDate"/>
  <property  name="content"/>
  
  <set  name="replys" lazy="false" fetch="join">
   <key column="topicid"/>
   <one-to-many class="com.SearchStrategy.Beforehand.Reply"/>
  </set>
 </class>

测试语句:

session.createQuery("from Topic").list();

hibernate发出的SQL语句:

Hibernate: 
    select
        topic0_.id as id0_,
        topic0_.title as title0_,
        topic0_.createDate as createDate0_,
        topic0_.content as content0_ 
    from
        Topic topic0_
Hibernate: 
    select
        replys0_.topicid as topicid0_2_,
        replys0_.id as id1_2_,
        replys0_.id as id1_1_,
        replys0_.createDate as createDate1_1_,
        replys0_.content as content1_1_,
        replys0_.topicId as topicId1_1_,
        topic1_.id as id0_0_,
        topic1_.title as title0_0_,
        topic1_.createDate as createDate0_0_,
        topic1_.content as content0_0_ 
    from
        Reply replys0_ 
    left outer join
        Topic topic1_ 
            on replys0_.topicId=topic1_.id 
    where
        replys0_.topicid=?
Hibernate: 
    ....  
   //省略N条reply的SQL查询语句,N 对应于Topic表的条数

四、批量检索策略

           又分为批量立即检索批量延迟检索两种。

1. 批量立即检索:

 批量立即检索是利用hibernate批量初始化要检索的实体类对象实例,发出批量查询SQL语句,从而减少SQL语句数量。

(1)Annotation:

使用@BatchSize(size=2)注解,不过使用hibernate4测试该注解无效。

(2)xml:

将<class>元素和<set>元素的lazy属性都设为false,并在<set>元素内添加batch-size属性。

 <class name="Topic" table="Topic" lazy="false">
  <id name="id">
   <column name="id"/>
   <generator class="native"/>
  </id>
  <property  name="title"/>
  <property  name="createDate"/>
  <property  name="content"/>
  
  <set  name="replys" lazy="false" batch-size="3">
   <key column="topicid"/>
   <one-to-many class="com.SearchStrategy.Batch.Reply"/>
  </set>
 </class>

测试语句:

session.createQuery("from Topic").list();
hibernate发出的SQL语句:

Hibernate: 
    select
        topic0_.id as id0_,
        topic0_.title as title0_,
        topic0_.createDate as createDate0_,
        topic0_.content as content0_ 
    from
        Topic topic0_
Hibernate: 
    select
        replys0_.topicid as topicid0_2_,
        replys0_.id as id1_2_,
        replys0_.id as id1_1_,
        replys0_.createDate as createDate1_1_,
        replys0_.content as content1_1_,
        replys0_.topicId as topicId1_1_,
        topic1_.id as id0_0_,
        topic1_.title as title0_0_,
        topic1_.createDate as createDate0_0_,
        topic1_.content as content0_0_ 
    from
        Reply replys0_ 
    left outer join
        Topic topic1_ 
            on replys0_.topicId=topic1_.id 
    where
        replys0_.topicid in (
            ?, ?, ?
        )
Hibernate: 
     ....  
    //省略 n 条reply的SQL查询语句,n 对应于Topic表的条数/batch-size +1


转载请注明转自本文,原文链接:http://blog.csdn.net/czw2010/article/details/8316413

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜之子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值