8.2 Compounding Criteria

     

As you might expect, you can add more than one Criterion to your query, and all of them must be satisfied for objects to be included in the results. This is equivalent to building a compound criterion using Expression.conjunction() , as described in Appendix B. As in Example 8-8, we can restrict our results so that the tracks also have to contain a capital 'A' somewhere in their title by adding another line to our method.

Example 8-8. A pickier list of short tracks
 Criteria criteria = session.createCriteria(Track.class); criteria.add(Expression.le("playTime", length));  criteria.add(Expression.like("title", "%A%"));  criteria.addOrder(Order.asc("title")); return criteria.list(); 

With this in place, we get fewer results (Example 8-9).

Example 8-9. Tracks of seven minutes or less containing a capital A in their titles
 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 

If you want to find any objects matching any one of your criteria, rather than requiring them to fit all criteria, you need to explicitly use Expression.disjunction() to group them. You can build up combinations of such groupings, and other complex hierarchies, using the built-in criteria offered by the Expression class. Check Appendix B for the details. Example 8-10 shows how we'd change the sample query to give us tracks that either met the length restriction or contained a capital A.

NOTE

Criteria queries are a surprising mix of power and convenience.

Example 8-10. Picking tracks more leniently
 Criteria criteria = session.createCriteria(Track.class);  Disjunction any = Expression.disjunction(); any.  add(Expression.le("playTime", length));  any.  add(Expression.like("title", "%A%"));  criteria.add(any);  criteria.addOrder(Order.asc("title"));         return criteria.list(); 

This results in us picking up a new version of 'Adagio for Strings' (Example 8-11).

Example 8-11. Tracks whose title contains the letter A, or whose length is seven minutes or less
 qtest:     [java] Track: "  A  dagio 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 

Finally, note that it's still possible, thanks to the clever return values of these methods , to consolidate our method into a single expression (Example 8-12).

Example 8-12. Taking code compactness a bit too far
 return session.createCriteria(Track.class).add(Expression.disjunction().  add(Expression.le("playTime", length)).add(Expression.like("title", "%A%"))).  addOrder(Order.asc("title")).list(); 

Although this yields the same results, I hope you agree it doesn't do good things for the readability of the method (except perhaps to LISP experts)!

You can use the facilities in Expression to build up a wide variety of multipart criteria. Some things still require HQL, and past a certain threshold of complexity, you're probably better off in that environment. But you can do a lot with criteria queries, and they're often the right way to go.



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