We have seen how you tell the query which objects you want. This section shows you how to also tell it how many objects you want, and what order you want them in.
public void setUnique (boolean unique); public void setRange (long start, long end);
Use the setUnique
method when you know your
query matches at most a single object. A unique query always returns
either the one candidate instance that matched the filter, or null; it
never returns a List
. In fact, unique
queries enforce the one-result rule by throwing a
JDOUserException
if more than one candidate survives the
filtering process.
While setUnique
is designed for queries with
only one result, setRange
is designed for those
with many. Most applications that deal with large amounts of data
only process or display a fixed number of records at a time. For
example, a web app might show the user 20 results per page, though many
thousands of records exist in the database. Using
setRange
, you can retrieve the exact range
of objects you're interested in. The method behaves much like
List.subList
or
String.subString
: it uses 0-based indexes, and the
end
index is exclusive. Unlike these methods,
however, setRange
won't throw an exception when
your range extends beyond the available elements. If 50 records exist
and you ask for the range 40, 60
, you'll
receive a list containing the 41st (remember indexes are 0-based)
through 50th result objects. If you ask for the range 60,
80
, you'll get an empty list.
Whenever you don't specify a range on a query, it defaults to a start
index of 0
and an end index of
Long.MAX_VALUE
, which represents no limit.
public void setOrdering (String ordering);
Ranges are meaningless if the result order isn't constant
between query executions, and many datastores don't guarantee
consistent natural ordering. setOrdering
gives you control over the order of results, so you don't have to rely
on the vagaries of the datastore. The method's argument is a
comma-separated list of field names or expressions, each followed by
the keyword ascending
or
descending
. Those keywords can be abbreviated as
asc
and desc
respectively.
Results are ordered primarily by the first (left-most) expression.
Wherever two results compare equal with that expression, the next
ordering expression is used to order them, and so on.
Example 11.11. Unique
Find the magazine "Spaces" published by Manning.
We know that this query can only match 0 or 1 magazines, so
we set the unique
flag to avoid having to
extract the result object from a List
.
PersistenceManager pm = ...; Query query = pm.newQuery (Magazine.class, "publisher.name == 'Manning' && title == 'Spaces'"); query.setUnique (true); processMagazine ((Magazine) query.execute ());
Example 11.12. Result Range and Ordering
Order all magazines by price and return the 21st through 40th results.
PersistenceManager pm = ...; Query query = pm.newQuery (Magazine.class); query.setOrdering ("price ascending"); query.setRange (20, 40); List mags = (List) query.execute (); for (Iterator itr = mags.iterator (); itr.hasNext ();) processMagazine ((Magazine) itr.next ()); query.close (mags);