8.1 Using Simple Criteria

     

Let's start by building a criteria query to find tracks shorter than a specified length, replacing the HQL we used in Example 3-9 and updating the code of Example 3-10.

8.1.1 How do I do that?

The first thing we need to figure out is how to specify the kind of object we're interested in retrieving. There is no query language involved in building criteria queries. Instead, you build up a tree of Criteria objects describing what you want. The Hibernate Session acts as a factory for these criteria, and you start, conveniently enough, by specifying the type of objects you want to retrieve.

Edit QueryTest.java , replacing the contents of the tracksNoLongerThan() method with those shown in Example 8-1.

Example 8-1. The beginnings of a criteria query
 public static List tracksNoLongerThan(Time length, Session session)     throws HibernateException {     Criteria criteria = session.createCriteria(Track.class);     return criteria.list(); } 

NOTE

These examples assume the database has been set up as described in the preceding chapters. If you don't want to go through all that, download the sample code, then jump into this chapter and run the ' codegen ', 'schema', and 'ctest' targets.

The session's createCriteria() method builds a criteria query that will return instances of the persistent class you supply as an argument. Easy enough. If you run the example at this point, of course, you'll see all the tracks in the database, since we haven't gotten around to expressing any actual criteria to limit our results yet (Example 8-2).

Example 8-2. Our fledgling criteria query returns all tracks
 %  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)" (ATB, William Orbit, 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 

OK, easy enough. How about picking the tracks we want? Also easy! Add a new import statement at the top of the file:

 import net.sf.hibernate.expression.*; 

Then just add one more line to the method, as in Example 8-3.

Example 8-3. The criteria query that fully replaces the HQL version from Chapter 3
 public static List tracksNoLongerThan(Time length, Session session)     throws HibernateException {     Criteria criteria = session.createCriteria(Track.class);  criteria.add(Expression.le("playTime", length));  return criteria.list(); } 

The Expression class acts as a factory for obtaining Criterion instances that can specify different kinds of constraints on your query. Its le() method creates a criterion that constrains a property to be less than or equal to a specified value. In this case we want the Track's playTime property to be no greater than the value passed in to the method. We add this to our set of desired criteria.

NOTE

Just like HQL, expressions are always in terms of object properties, not table columns .

We'll look at some other Criterion types available through Expression in the next section. Appendix B lists them all, and you can create your own implementations of the Criterion interface if you've got something new you want to support.

Running the query this time gives us just the tracks that are no more than seven minutes long, as requested by the main() method (Example 8-4).

Example 8-4. Results of our complete simple criteria query
 %  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: "Test Tone 1" 00:00:10     [java]   Comment: Pink noise to test equalization 

A surprising number of the queries used to retrieve objects in real applications are very simple, and criteria queries are an extremely natural and compact way of expressing them in Java. Our new tracksNoLongerThan() method is actually shorter than it was in Example 3-10, and that version required a separate query (Example 3-9) to be added to the mapping document as well! Both approaches lead to the same patterns of underlying database access, so they are equally efficient at runtime.

In fact, you can make the code even more compact. The add() and createCriteria() methods return the Criteria instance, so you can continue to manipulate it in the same Java statement. Taking advantage of that, we can boil the method down to the version in Example 8-5.

Example 8-5. An even more compact version of our criteria query
 public static List tracksNoLongerThan(Time length, Session session)     throws HibernateException {  return session.createCriteria(Track.class).        add(Expression.le("playTime", length)).list();  } 

The style you choose is a trade-off between space and readability (although some people may find the compact, run-on version even more readable). Even though this is marked as an experimental API, it already looks extremely useful, and I expect to adopt it in many places.

8.1.2 What about...

...Sorting the list of results, or retrieving a subset of all matching objects? Like the Query interface, the Criteria interface lets you limit the number of results you get back (and choose where to start) by calling setMaxResults() and setFirstResult() . It also lets you control the order in which they're returned (which you'd do using an order by clause in an HQL query), as shown in Example 8-6.

Example 8-6. Sorting the results by title
 public static List tracksNoLongerThan(Time length, Session session)     throws HibernateException {     Criteria criteria = session.createCriteria(Track.class);     criteria.add(Expression.le("playTime", length));     criteria.addOrder(Order.asc("title"));     return criteria.list(); } 

The Order class is just a way of representing orderings. It has two static factory methods, asc() and desc() , for creating ascending or descending orderings respectively. Each takes the name of the property to be sorted. The results of running this version are in Example 8-7.

Example 8-7. The sorted results
 %  ant qtest  ... qtest:     [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 

You can add more than one Order to the Criteria , and it will sort by each of them in turn (the first gets priority, and then if there are any results with the same value for that property, the second ordering is applied to them, and so on).



Hibernate. A Developer's Notebook
Hibernate: A Developers Notebook
ISBN: 0596006969
EAN: 2147483647
Year: 2003
Pages: 65
Authors: James Elliott

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net