生成Java类
使用hibernate tools(hbm2java)
自定义类型关联
实现UserType接口或者CompositeUserType接口
扩充集合中的关联
第五章比较复杂,中文版的89页。
Hibernate支持映射标注
请参考http://annotations.hibernate.org
在XML建立查询语句
在HBM文件加入查询语句,具体在</hibernate-mapping>那一行的前面。
<query name="com.oreilly.hh.tracksNoLongerThan">
<![CDATA[
from Track as track
where track.playTime <= :length
]]>
</query>
然后建立query时调用getNamedQuery("com.oreilly.hh.tracksNoLongerThan")
条件查询
criteria.add
模糊查询Restrictions.like("title", "%A%")
不想写%的话可以使用Restrictions.like("title", "%A%", MatchMode.ANYWHERE)
如果想进行区分大小写的批评,应该是使用ilike,而不是like
如果你希望找出满足任意条件之一的对象,而非满足所有条件的对象,就得显式的使用Restrictions.disjunction()将这些条件分组。
Criteria criteria = session.createCriteria(Track.class);
Disjunction any = Restrictions.disjunction();
any.add(Restrictions.le("playtime", length));
any.add(Restrictions.le("title", "%A%");
criteria.add(any);
投影
criteria.setProjection(Projections.property("title"));
return criteria.list();
多个投影返回的是Array
/**
* Retrieve the titles and play times of any tracks that contain a
* particular text string.
*
* @param text the text to be matched, ignoring case, anywhere in the title.
* @param session the Hibernate session that can retrieve data.
* @return the matching titles and times wrapped in object arrays.
*/
public static List titlesContainingTextWithPlayTimes(String text,
Session session) {
Criteria criteria = session.createCriteria(Track.class);
criteria.add(Restrictions.like("title", text, MatchMode.ANYWHERE)
.ignoreCase());
criteria.setProjection(Projections.projectionList().
add(Projections.property("title")).
add(Projections.property("playTime")));
return criteria.list();
}
带聚合的投影
/**
* Print statistics about various media types.
*
* @param session the Hibernate session that can retrieve data.
*/
public static void printMediaStatistics(Session session) {
Criteria criteria = session.createCriteria(Track.class);
criteria.setProjection(Projections.projectionList().
add(Projections.groupProperty("sourceMedia").as("media")).
add(Projections.rowCount()).
add(Projections.max("playTime")));
criteria.addOrder(Order.asc("media"));
for (Object o : criteria.list()) {
Object[] array = (Object[])o;
System.out.println(array[0] + " track count: " + array[1] +
"; max play time: " + array[2]);
}
}
示例查询
/**
* Retrieve any tracks that were obtained from a particular source media
* type.
*
* @param media the media type of interest.
* @param session the Hibernate session that can retrieve data.
* @return a list of {@link Track}s meeting the media restriction.
*/
public static List tracksFromMedia(SourceMedia media, Session session) {
Track track = new Track();
track.setSourceMedia(media);
Example example = Example.create(track);
Criteria criteria = session.createCriteria(Track.class);
criteria.add(example);
criteria.addOrder(Order.asc("title"));
return criteria.list();
}
默认的行为是,值为null的属性将被忽略,对字符串值按照区分大小写的、逐字的方式进行比较。如果想在比较时忽略值为0的属性。,可以调用example的excludeZeros()方法;或者,如果希望对值为null的属性进行匹配,可以调用excludeNone()。而excludeProperty()方法则可以让你明确忽略指定名称的特定属性,不过这像是在手工构建条件查询。为了调整字符串处理。还可以使用ignoreCase()和enableLike()方法,从他们的名字可以知道各自的用途。
面向属性的criteria
以前
criteria.add(Restrictions.le("playTime", length));
而是用
criteria.add(
Property,forName("playTime").le(length));
criteria.addOrder(Order.asc("name").ignoreCase());
而是用
criteria.addOrder(
Property.forName("name").asc().ignoreCase());
投影
criteria.setProjection(Projections.max("playTime"));
等价的方法
criteria.setProjection(
Property.forName("playTime").max());
浅谈HQL
比较代表性的例子
<query name="com.oreilly.hh.tracksNoLongerThan">
<![CDATA[
select track.id, track.title from Track as track
where track.playTime <= :length
order by track.title desc
]]>
</query>
<query name="com.oreilly.hh.trackSummary">
<![CDATA[
select count(*), min(track.playTime), max(track.playTime)
from Track as track
where :artist in elements(track.artists)
]]>
</query>
原生SQL查询
<sql-query name="com.oreilly.hh.tracksEndingAt">
<return alias="track" class="com.oreilly.hh.data.Track"/>
<![CDATA[
select {track.*}
from TRACK as {track}
where SECOND({track}.PLAYTIME) = :seconds
]]>
</sql-query>
return是告诉hibernate,我们准备再查询中使用track别名来引用Track对象,这样就能够在查询语句中使用简写的{track.*}来引用TRACK数据表中所需要的所有字段以创建Track实力(注意,在查询语句中这样使用别名时,必须用大括号将别名括起来。这能让我们“脱离”原生SQL语句环境,用hibernate映射类和属性来描述查询内容)
注:此书看完后并不会精通hibernate...要想达到精通,还是看看《java persistence with hibernate》吧
PS:附件为《精通hibernate》中的源码。