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. |