返回介绍

组合式条件查询

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

可以想到,如果在查询中添加多个 Criterion,那么结果中的对象就得满足所有的 Criterion。这相当于使用 Restrictions.conjunction()建立一个组合条件,详情可以参阅附录 B。就例 8-8 来说,我们可以限制查询结果,所以在该方法中另加一行,使得曲目的标题中必须包含字母"A"。

例 8-8:一个较挑剔的条件查询

Criteria criteria=session.createCriteria(Track.class);

criteria.add(Restrictions.le("playTime",length));

criteria.add(Restrictions.like("title","%A%"));

criteria.addOrder(Order.asc("title").ignoreCase());

return criteria.list();

准备好以后,运行程序,这次会得到较少的结果,如例 8-9 所示。

例 8-9:播放时间等于或少于 7 分钟且标题包含字母"A"的曲目

qtest:

[java]Track:"Adagio for Strings(Ferry Corsten Remix)"(Samuel Barber,

Ferry Corsten, William Orbit)00:06:35,from Compact Disc

[java]Track:"Gravity's Angel"(Laurie Anderson)00:06:06,from

Compact Disc

如果你不记得(或不知道)像这样的 SQL“%”字符串匹配的语法,Hibernate 还提供了一个可供调用的参数变量,用于在 Java 中表达你需要的任何匹配。就这个例子来说,可以写成 Restrictions.like("title","A",MatchMode.ANYWHERE)。如果你想进行区分大小写的匹配,应该使用 ilike,而不是 like。

如果你希望找出满足任意条件之一的对象,而非满足所有条件的对象,就得显式的使用 Restrictions.disjunction()将这些条件分组。可以使用 Restrictions 类提供的 Criteria 工厂来建立这些分组以及其他复杂层次的组合。详情可以参阅附录 B。例 8-10 演示了我们对示例查询的修改,让返回的曲目既满足时间长度限制又满足标题包含大写字母 A。

注意:条件查询结合了强大的功能和方便性,令人吃惊。

例 8-10:限制较宽松的条件查询

Criteria criteria=session.createCriteria(Track.class);

Disjunction any=Restrictions.disjunction();

any.add(Restrictions.le("playTime",length));

any.add(Restrictions.like("title","%A%"));

criteria.add(any);

criteria.addOrder(Order.asc("title").ignoreCase());

return criteria.list();

这会让我们多获取一个新的"Adagio for Strings"曲目(如例 8-11 所示)。

例 8-11:标题含有字母"A"或者时间不超过 7 分钟的曲目

qtest:

[java]Track:"Adagio for Strings(ATB Remix)"(ATB, William Orbit,

Samuel Barber)00:07:39,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:"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

最后要注意的是,把这个方法精简到一个表达式也是可行的(如例 8-12 所示)。这得多亏这些方法的设计精巧的返回值。

例 8-12:代码精简得有些过头

return session.createCriteria(Track.class).add(Restrictions.disjunction().

add(Restrictions.le("playTime",length)).

add(Restrictions.like("title","%A%"))).

addOrder(Order.asc("title").ignoreCase()).list();

虽然得到的结果都一样,但我觉得你也会认为这样做对该方法代码的可读性没有什么帮助(可能 LISP 专家不算在内吧)!

可以用 Restrictions 提供的工具来建立各种各样的多重条件。有些情况还得需要 HQL,而且超过一定的复杂度的话,可能还是用 HQL 比较好。但是,条件查询能够让你做很多事情,这常常是正确的做法。

发布评论

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