
	The javax.jdo.Query interface serves two functions: 
	object filtering and data retrieval.  This chapter examines each in turn.
	
| ![[Note]](img/note.gif) | Note | 
|---|---|
| 
		Kodo extends the standard  | 
		JDO queries evaluate a group of candidate objects against a set of 
		conditions, eliminating the objects that don't match.  We refer to 
		this as object filtering.  The original group of 
		objects might be a Collection of instances 
		you've already retrieved, or an Extent.  Recall 
		from Chapter 10, Extent that an Extent
		 represents all persistent instances of a certain class,
		optionally including subclasses.
		
Filter conditions are specified in the JDO Query Language (JDOQL). The filtering process might take place in the datastore, or might be executed in memory. JDO does not mandate any one mechanism, and many implementations use a mixture of datastore and in-memory execution depending on the circumstances.
		Basic object filtering utilizes the following Query
		 methods:
		
public void setClass (Class candidateClass); public void setCandidates (Extent candidates); public void setCandidates (Collection candidates); public void setFilter (String filter);
				
				
				
				setClass names the candidate class.  
				Candidate objects that are not assignable to the candidate
				class cannot match the filter.
				
				
				
				
				The two setCandidates methods specify
				the set of objects to evaluate.  If you supply an 
				Extent, you don't need to also call 
				setClass; the Query
				 inherits the 
				Extent's candidate class.  Reciprocally,
				if you call setClass but do not call 
				either setCandidates method, the query
				candidates default to the Extent of the 
				candidate class, including subclasses.
				
				
				
				
				setFilter accepts a JDOQL string 
				establishing the conditions an object must meet to be included 
				in the query results.  As you'll see shortly, JDOQL looks 
				exactly like a Java boolean expression using the candidate 
				class' persistent fields and relations.  When you don't set a 
				filter explicitly, it defaults to the simplest possible boolean
				expression: true.  In this case, all 
				candidate objects assignable to the candidate class match 
				the query.
				
Let's see an example of basic object filtering in action. Our example draws on the following subset of the object model defined in Chapter 5, Metadata. We use this model subset throughout this chapter.

Example 11.1. Filtering
			The following code processes all Magazine
			objects in the database whose price is greater than 10 dollars.
			
PersistenceManager pm = ...;
Query query = pm.newQuery ();
query.setClass (Magazine.class);
query.setCandidates (pm.getExtent (Magazine.class, true));
query.setFilter ("this.price > 10");
List mags = (List) query.execute ();
for (Iterator itr = mags.iterator (); itr.hasNext ();)
    processMagazine ((Magazine) itr.next ());
query.close (mags);
			The code above is technically correct, but could be much more 
			concise.  First, remember that setting a candidate class defaults 
			the candidates to the Extent of that class, 
			and vice versa.  So we 
			don't need both the setClass 
			and setCandidates calls.  We can also get
			rid of the this qualifier on price
			 in our filter string, since unqualified field names are 
			already assumed to belong to the current object, just as in Java
			code.  Finally, we can take advantage of the fact that 
			PersistenceManager overloads the 
			newQuery method to tighten our code 
			further.  Here is the revised version:
			
PersistenceManager pm = ...;
Query query = pm.newQuery (Magazine.class, "price > 10");
List mags = (List) query.execute ();
for (Iterator itr = mags.iterator (); itr.hasNext ();)
    processMagazine ((Magazine) itr.next ());
query.close (mags);
The filter above is rather basic. Before moving on to more advanced queries, though, we need to dive into the details of JDOQL.
|    |