返回介绍

使用简单条件查询

发布于 2025-04-21 21:42:13 字数 4981 浏览 0 评论 0 收藏

我们先建一个条件查询来查找播放时间少于指定长度的曲目,将例 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 进行排序,依此类推)。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。