返回介绍

示例查询

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

如果你觉得建立表达式和查询条件麻烦,而你又有个对象能展示出要寻找的目标,就能够以它为示例,让 Hibernate 为你建立查询条件。

应该怎么做

我们需要在 QueryTest.java 里新增加另一个查询方法,将例 8-19 的代码添加到其他查询所在类的顶端。

例 8-19:使用示例实体来生成条件查询

/**

*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();

}

❶我们先创建示例用的 Track 实例,再设置 sourceMedia 属性,以表示我们要查询的内容。

❷接着将它包装到一个 Example 对象中。这个对象可以在一定程度上让你控制在构建条件查询时将会用什么属性,以及如何匹配字符串。默认的行为是,值为 null 的属性将被忽略,对字符串值按照区分大小写的、逐字的方式进行比较。如果想在比较时忽略值为 0 的属性,可以调用 example 的 excludeZeroes()方法;或者,如果希望对值为 null 的属性进行匹配,可以调用 excludeNone()。而 excludeProperty()方法则可以让你明确地忽略指定名称的特定属性,不过这很像是在手工构建条件查询。为了调整字符串处理,还可以使用 ignoreCase()和 enableLike()方法,从它们的名字可以知道各自的用途。

❸接着,我们创建一个条件查询,就像本章的其他例子一样,不同的是这里为条件查询增加的是 example,而不是使用 Restrictions 来创建 Criterion。Hibernate 会负责将 example 转换成相应的 criteria。其他代码行与我们前面的查询方法类似:建立排序序列,运行查询,返回匹配的实体列表。

同样地,为了调用新的查询方法,我们也必须修改 main()方法。把来自 CD 的曲目都找出来吧。修改之处如例 8-20 所示。

例 8-20:修改 main()方法,以调用示例驱动的查询方法

……

//Ask for a session using the JDBC information we've configured

Session session=sessionFactory.openSession();

try{

//Print tracks that came from CDs

List tracks=tracksFromMedia(SourceMedia.CD, session);

for(ListIterator iter=tracks.listIterator();

……

运行这个版本的示例,产生的输出如例 8-21 所示。

例 8-21:以示例查询来自 CD 的曲目的结果

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

William Orbit)00:07:39,from Compact Disc

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

Barber, William Orbit, Ferry Corsten)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

你可能觉得这个例子有些做作,因为我们并没有合适的 Track 对象可以作为示例,因此得在这个方法中创建一个示例。嗯,也许吧,但是采用此方法有个很有价值的理由:与纯条件查询相比,这种方法在编译期间会做更多的检查。虽然条件查询可以避免 HQL 查询在运行时的语法结构错误,但你还是可能会弄错属性的名称。而这些错误是编译器无法捕获的,因为名称只是字符串而已。当你建立示例查询时,实际上是以该实体的存取器方法( [1] )(mutator method)来设置属性值的内容。这意味着,如果你输入错字,Java 会在编译期间就捕获到它。

你大概想得到,也可以让子条件查询(subcriteria)使用示例来查询相关联的对象。我们可以重写 tracksWithArtistLike(),使用一个作为示例用的 Artist 对象,而非自己手工建立查询条件。最后再调用示例对象的 enableLike()方法。例 8-22 演示了完成这一功能的简洁方法。

例 8-22:更新艺人姓名查询,使用一个艺人对象作为示例

public static List tracksWithArtistLike(String namePattern, Session session)

{

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

Example example=Example.create(new Artist(namePattern, null, null));

criteria.createCriteria("artists").add(example.enableLike()).addOrder(

Order.asc("name").ignoreCase());

return criteria.list();

}

这一过程的输出与我们前面“手工”构建的内部条件查询生成的输出完全一样。如果你想运行这个例子,记得把 main()换回例 8-17 的样子。

注意:条件查询相当简单,对吧?和原来 Hibernate 2 中的相比,现在它们的功能更强大,我更喜欢它们了。

各种各样的查询可以增强用户界面的功能,数据驱动(data-driven)的 Java 应用程序的典型操作也可以表示成条件查询。在可读性、编译期类型检查甚至是代码紧凑性(令人惊讶)等各方面,条件查询都有其优点。就目前这些新的数据库 API 而言,我认为条件查询是赢家。

[1] 存取器方法指对象提供的用于访问其实例变量接口的方法。用于返回实例变量值的存取器方法称为获取方法(即 get 方法);用于为实例变量赋值的存取器方法称为设置方法(即 set 方法)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

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