- 译者序
- 前言
- 本书怎么使用
- 本书排版字体约定
- 本书网站
- 致谢
- 第一部分 Hibernate 快速入门
- 第 1 章 安装和设置
- 第 2 章 映射简介
- 第 3 章 驾驭 Hibernate
- 第 4 章 集合与关联
- 第 5 章 更复杂的关联
- 第 6 章 自定义值类型
- 第 7 章 映射标注
- 第 8 章 条件查询
- 第 9 章 浅谈 HQL
- 第二部分 与其他工具的集成
- 第 10 章 将 Hibernate 连接到 MySQL
- 第 11 章 Hibernate 与 Eclipse:Hibernate Tools 使用实战
- 第 12 章 Maven 进阶
- 第 13 章 Spring 入门:Hibernate 与 Spring
- 第 14 章 画龙点睛:用 Stripes 集成 Spring 和 Hibernate
- 附录 A Hibernate 类型
- 附录 B Criteria API
- 附录 C Hibernate SQL 方言
- 附录 D Spring 事务支持
- 附录 E 参考资源
- 作者简介
- 封面介绍
使用简单条件查询
我们先建一个条件查询来查找播放时间少于指定长度的曲目,将例 3-11 中所用的 HQL 替换掉,并更新例 3-12 的代码。
应该怎么做
需要明白的第一件事就是如何指定我们想要检索的对象的类型。在建立条件查询时,不会涉及任何查询语言。相反,你得构建一个由 Criteria 对象组成的树状结构来描述你需要检索的对象。Hibernate Session 就是创建这些 Criteria 对象的工厂,而你需要做的就是指定想要检索到的对象的类型,够方便的吧。
编辑 QueryTest.java,将 tracksNoLongerThan()方法的内容替换成例 8-1 所示的内容。
注意:这些示例假设已经按照前几章所述建立好了数据库。如果你不想从头开始,就下载示例代码,然后再跳到这一章的目录,运行 codegen、schema、以及 ctest 这几个构建目标。即使你按照书中介绍一路走来,运行 schema 和 ctest 也将确保生成这些示例展示的数据。
例 8-1:条件查询入门
public static List tracksNoLongerThan(Time length, Session session){
Criteria criteria=session.createCriteria(Track.class);
return criteria.list();
}
会话对象的 createCriteria()方法会创建一个条件查询对象(Criteria 类的实例),由它返回作为参数传递给它的持久化类的所有实例,真够简单的。当然,如果现在运行示例,会看到数据库中保存的所有曲目,因为我们还没有使用任何查询条件(criteria)来限制查询结果(如例 8-2 所示)。
例 8-2:羽翼未丰的条件查询将返回所有曲目
%ant qtest
……
qtest:
[java]Track:"Russian Trance"(PPK)00:03:30,from Compact Disc
[java]Track:"Video Killed the Radio Star"(The Buggles)00:03:49,
from VHS Videocassette tape
[java]Track:"Gravity's Angel"(Laurie Anderson)00:06:06,from Compact
Disc
[java]Track:"Adagio for Strings(Ferry Corsten Remix)"(Ferry Corsten,
William Orbit, Samuel Barber)00:06:35,from Compact Disc
[java]Track:"Adagio for Strings(ATB Remix)"(William Orbit, ATB,
Samuel Barber)00:07:39,from Compact Disc
[java]Track:"The World'99"(Ferry Corsten, Pulp Victim)00:07:05,
from Digital Audio Stream
[java]Track:"Test Tone 1"00:00:10
[java]Comment:Pink noise to test equalization
好,够简单。那么,应该怎么挑选出我们想要的曲目?也很简单!只要在源文件顶端新增加一行:
import org.hibernate.criterion.*;
然后,再在这个方法中新增加一行,如例 8-3 所示。
例 8-3:用 Criteria 查询完全取代第 3 章使用的 HQL 查询
public static List tracksNoLongerThan(Time length, Session session){
Criteria criteria=session.createCriteria(Track.class);
criteria.add(Restrictions.le("playTime",length));
return criteria.list();
}
注意:就像 HQL 那样,表达式总是以对象属性来表示,而不使用数据表的字段。
Restrictions 类是一个工厂类,用于获取在查询中指定各种约束条件的 Criterion 实例。它的 le()方法会创建一个 Criterion 对象,限制一个属性必须小于或等于指定的值。在这个例子中,我们想让 Track 的 playTime 属性不大于传递给该方法的值。最后再把它添加到所要的条件查询组合中。下一节我们将会看到其他几个通过 Restrictions 能用的 Criterion 类型。附录 B 会列出全部的 Criterion 类型,如果你想支持新的条件形式,也可以自行创建 Criterion 接口的实现。
这次运行查询时,会得到长度不超过 7 分钟的曲目,如例 8-4 所示。
例 8-4:完整的简单条件查询的结果
%ant qtest
……
qtest:
[java]Track:"Russian Trance"(PPK)00:03:30,from Compact Disc
[java]Track:"Video Killed the Radio Star"(The Buggles)00:03:49,
from VHS Videocassette tape
[java]Track:"Gravity's Angel"(Laurie Anderson)00:06:06,from
Compact Disc
[java]Track:"Adagio for Strings(Ferry Corsten Remix)"(Ferry Corsten,
Samuel Barber, William Orbit)00:06:35,from Compact Disc
[java]Track:"Test Tone 1"00:00:10
[java]Comment:Pink noise to test equalization
注意:本书新版修订了这个示例,"Adagio for Strings"会在 iTunes 中随机开始播放。
在实际应用中,绝大多数用于检索对象的查询都是非常简单的,而条件查询更是用 Java 表达这些查询时极为自然和简洁的方式。新的 tracksNoLongerThan()方法实际上比例 3-12 和那个需要将查询添加到映射文件的示例(例 3-11)还要短!不过,它们最终都以相同的模式来访问底层数据库,所以运行效率相当。
不过,如果需要的话,也可以把代码写得更紧凑些。Add()和 createCriteria()方法会返回 Criteria 实例,所以可以在同一 Java 语句中连续操作该实例。利用这一点,我们就能把这个方法再归纳一下,变成例 8-5 的样子。
例 8-5:更为紧凑的条件查询
public static List tracksNoLongerThan(Time length, Session session){
return session.createCriteria(Track.class).
add(Restrictions.le("playTime",length)).list();
}
选择编码风格就是在空间和可读性之间做出取舍(不过,有些人会觉得这种紧凑、连续编码的版本更具可读性)。
其他
对结果进行排序?从所有匹配的对象中取回它们的一部分?和 Query 接口一样,Criteria 接口也可以让你调用 setMaxResults()和 setFirstResult()方法来限制取回的结果数目(以及选择从哪里开始)。此外,这个接口也可以让你控制结果返回的顺序(在 HQL 查询中,则是使用 order by 子句),如例 8-6 所示。
例 8-6:按照标题对结果进行排序
public static List tracksNoLongerThan(Time length, Session session){
Criteria criteria=session.createCriteria(Track.class);
criteria.add(Restrictions.le("playTime",length));
criteria.addOrder(Order.asc("title").ignoreCase());
return criteria.list();
}
Order 类只是表达排列顺序的一种方式。它有两个静态的工厂方法:asc()和 desc()方法,分别用于创建升序和降序的排列。每个方法都以要排序的属性名称作为参数。如果调用 Order 实例的 ignoreCase()方法,则排序将不区分字母的大小写,这经常是你想要的显示方式。运行这个版本的示例,其结果如例 8-7 所示。
例 8-7:对检索结果进行排序
%ant qtest
……
qtest:
[java]Track:"Adagio for Strings(Ferry Corsten Remix)"(Ferry Corsten,
Samuel Barber, William Orbit)00:06:35,from Compact Disc
[java]Track:"Gravity's Angel"(Laurie Anderson)00:06:06,from Compact
Disc
[java]Track:"Russian Trance"(PPK)00:03:30,from Compact Disc
[java]Track:"Test Tone 1"00:00:10
[java]Comment:Pink noise to test equalization
[java]Track:"Video Killed the Radio Star"(The Buggles)00:03:49,
from VHS Videocassette tape
可以在 Criteria 添加多个 Order,这样 Criteria 就会按每个 Order 的先后进行排序(先按第一个 Order 排序,如果有任何查询结果与那个属性具有相同的值,就再按第二个 Order 进行排序,依此类推)。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论