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方法 }
立即检索指的是在加载一个对象时不仅立即加载该对象,并且还会立即加载与该对象相关联的其他对象。例如:查询一个帖子信息时,会将该帖子所关联的所有回复查询出来。
使用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方法 }
需要将<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表的条数
延迟加载是指对象在使用到时才会进行加载。
@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方法 }
需要将<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=?
预先加载指的是一种通过左外连接来获得对象关联实例或者集合的检索方法,主要用于关联级别的查询。
将<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表的条数
又分为批量立即检索和批量延迟检索两种。
批量立即检索是利用hibernate批量初始化要检索的实体类对象实例,发出批量查询SQL语句,从而减少SQL语句数量。
使用@BatchSize(size=2)注解,不过使用hibernate4测试该注解无效。
将<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