The Query Interface


The Query interface is used to construct and execute queries. Figure 2-2 shows the class diagram of the Query interface. 20 methods define the 11 operations and 5 properties shown in Figure 2-2.

click to expand
Figure 2-2: The class diagram of the Query interface

Queries are serializable and can be stored. A deserialized query is no longer related to its original persistence manager. For that reason, the only use for a deserialized query is to obtain a new query with all the same settings from any open persistence manager. The newly obtained query is related to the persistence manager that produced it. It is not compiled, and its candidates are not set. Otherwise, its settings are the same as the original query.

After configuration, a query can be executed any number of times in the same transaction or in different transactions. Each time the query executes, it selects objects from the candidates based on the query filter, the candidate class, and the parameter values. The query returns the selected objects in the results collection. The results collection is empty when no candidates satisfy the query.

Setting the Query's Candidates

The Query interface provides two methods to set the query's candidates.

 public void setCandidates(Extent extent) public void setCandidates(java.util.Collection collection) 

When queries are executed, they select objects from a range of candidates. These methods specify the range as either an extent or a collection. If a collection is used, it must contain persistent objects that are managed by the same persistence manager that produced the query. If an extent is used, it must come from the same persistence manager that created the query. Using an extent to set the query's candidates is a hint to the JDO implementation to send the query to the datastore service. Using a collection, on the other hand, usually causes the JDO implementation to execute the query against objects in memory.

Setting the Query's Candidate Class

The Query interface provides a setter method for its write-only Class property. This property is also called the query's candidate class.

 public void setClass(Class candidateClass) 

Queries select objects from the candidates that are assignment compatible with the query's candidate class. The candidate class is always an application data class. When the query's candidate class is set, but the query's candidates are not set, the query uses by default the extent associated with the query's candidate class. In other words, if you want to run a query against an extent, you have the option of setting only the Class property and ignoring the Candidates property.

Generally, when queries run against extents, the candidate class of the query is the same as the candidate class of the extent. The ability to independently set the query's candidate class becomes important when the query runs against a collection of candidate objects, as the collection may contain objects of different classes.

Setting the Query's Filter

The Query interface provides a setter method for its write-only Filter property.

 public void setFilter(String filter) 

The query selects matching candidates on the basis of a query string, which is stored in the write-only Filter property. Later sections of this chapter, starting with "The Syntax of the JDO Query Filter," describe the syntax and semantics of the JDO Query Language (JDOQL) used in the query filter.

Declaring the Query's Parameters

The Query interface provides a method to declare the parameters that can be passed when invoking the query.

 public void declareParameters(String paramString) 

The query filter may, or may not, use query parameters. By declaring parameters, the application can determine at runtime the values to be used in the query filter. The application declares parameters by passing a string to the query's declareParameters method. The syntax of this string is the same as the parameter declaration clause in a Java method. For example, the following string declares two parameters of types Foo and Bar:

 "Foo foo, Bar bar" 

The following string declares one integer and two Date parameters:

 "int count, Date yesterday, Date today" 

All of the parameters must be declared in one parameter string, and the names must be distinct. Field names in the candidate class, parameter names, and variable names share the same name space. If a parameter name is the same as the name of a field in the candidate class, the field name is hidden. The field name may still be accessed in the query filter by using the this.fieldname syntax.

JDO allows the application to declare parameters of primitive types, but the parameters passed to the query's execute methods must be objects of the corresponding wrapper types. When the declared parameter is a primitive, the wrapper object passed to the execute method cannot be null. JDO implementations may require that parameters be primitives or persistent-capable types. They may also require that all application data objects be managed. In all cases, if the object passed as a parameter value is managed, it must be managed by the persistence manager that produced the Query object. Using transient application data objects and objects of classes that are not persistence-capable for parameter values is not portable across JDO implementations.

Declaring the Query's Variables

The Query interface provides a method to declare the variables that can be used in the query filter.

 public void declareVariables(String varString) 

By using variables, the application can construct more complex query filters. Later sections of this chapter, starting with "Query Variables," describe the syntax and semantics of the variable string and the use of variables in the query filter.

Declaring the Query's Imports

The Query interface provides a method to declare the types that must be imported into the query's name space.

 public void declareImports(String importString) 

In some cases, the declared parameters and variables, or the query filter, require the importing of type names. The declareImports method sets the string that handles this need. The type of the candidate class, all the types in the package containing the candidate class, and all the types in the java.lang package are automatically imported. Otherwise, the class or interface type must be imported unless it is fully qualified when used in the filter, parameter, or variable strings.

The imports string has the same syntax as the Java import statement. For example, the following import string identifies another place where the query can look to find classes used in variables and parameters:

 "import example.persistent.*;" 

Wildcards are permitted but not required in the import string. The import string may contain multiple import statements separated by semicolons. All import statements must be contained in one string.

Ordering the Results

The Query interface provides a setter method for its write-only Ordering property.

 public void setOrdering(String orderingString) 

The order of iteration for the objects returned in the results collection is specified by an ordering string that is stored in the write-only Ordering property. The "Ordering Results" section later in this chapter describes the ordering string in detail.

Running the Query

The Query interface provides six methods to run the query. Most of these methods take parameters that are used when evaluating the query filter.

 public Object execute() public Object execute(Object param1) public Object execute(Object param1, Object param2) public Object execute(Object param1, Object param2, Object param3) public Object executeWithArray(Object [] params) public Object executeWithMap(Map params) 

Each of the five methods that execute a query returns the selected objects in a Collection called the results collection. The results collection is returned as an Object and must be cast to Collection. The objects included in the results collection are assignment compatible with the query's candidate class. The results collection cannot be modified. Any attempt to modify the returned collection results in a java.lang.UnsupportedOperationException.

The results collection may be very large, but it can always be iterated. The returned collection may be used in another query. The results collection returns a value for the size method. This value may be the size of the collection, or it may be Integer.MAX_VALUE when the JDO implementation does not know the size.

The parameters of the execute methods are matched left to right with the parameter names declared in the parameter string. The executeWithArray method accepts an array of values. The parameter at index zero is matched with the leftmost parameter in the parameter string. The executeWithMap method accepts a Map object that contains the parameters. The keys in the map are matched by name to the names in the parameter string, and the value associated with the key is used as the parameter's value.

The query must pass values for all declared parameters in each execution of the query. The query does not remember the parameter values used in an earlier execution of the query.

For the execute methods to succeed, the persistence manager that produced the query must be open and either the transaction must be active or the transaction's NontransactionalRead property must be true. Otherwise, the execute methods throw a JDOUserException. Chapter 3 describes the PersistenceManager interface, and Chapter 4 describes the Transaction interface and its properties.

Closing the Query's Results

The Query interface provides two methods to close the results collections obtained from running queries.

 public void close(Object resultsCollection) public void closeAll() 

The results collection is an instance of a collection class supplied by the JDO implementation. It may use resources in the datastore. When the results collection is no longer needed, it should be closed. The close method closes one results collection produced by the query. The closeAll method closes all open results collections produced by the query.

When a results collection is obtained by executing a query in a transaction, the specification does not define how the results collection behaves when it is left open after the transaction ends. Any behavior that you observe is likely to be implementation dependent. For portability, the application should close any results collections that it obtained within the transaction either before or immediately after completing the transaction.

After the results collection is closed, it can no longer be used or iterated. Existing iterators on the results collection return false from the hasNext method and throw the NoSuchElementException from the next method. The application can continue to use the persistent objects that it found in the results collection prior to closing it.

Compiling a Query

The Query interface provides a method to compile a query prior to using it.

 public void compile() 

Although any query can be compiled, because queries that use parameters are often reused, it makes sense to compile them. The implementation can optimize compiled queries for higher performance. In the case of a relational datastore, the compiled query is likely to use a prepared statement for faster performance. Compiling a query may detect problems with the query's configuration prior to execution.

The IgnoreCache Property

The Query interface provides getter and setter methods for its IgnoreCache property.

 public void setIgnoreCache(boolean flag) public boolean getIgnoreCache() 

The read-write IgnoreCache property in the Query interface determines whether the query uses the data objects that are persistent-new, persistent-deleted, and persistent-dirty in determining the results of executing a query against an extent. The initial value of the IgnoreCache property is inherited from the persistence manager that produced the Query object. The section "Using or Ignoring the Cache in a Query" later in this chapter examines this property in detail.

The Read-Only PersistenceManager Property

The Query interface provides a getter method for its read-only PersistenceManager property.

 public PersistenceManager getPersistenceManager() 

This method returns a reference to the persistence manager that produced the query.




Using and Understanding Java Data Objects
Using and Understanding Java Data Objects
ISBN: 1590590430
EAN: 2147483647
Year: 2005
Pages: 156
Authors: David Ezzio

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