Title: Customizing Queries
Any object that implements org.objectstyle.cayenne.query.Query interface can be executed with a DataContext.
The interface defines the following methods (ommitting irrelevant deprecated ones):
public interface Query extends Serializable { String getName(); QueryMetadata getMetaData(EntityResolver resolver); void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery); SQLAction createSQLAction(SQLActionVisitor visitor); }
One customization strategy is an "indirect" query that encapsulates some user-defined operation and in runtime resolves to one or more standard Cayenne queries. Indirect queries can be created from scratch or by extending org.objectstyle.cayenne.query.IndirectQuery. As an example lets implement a "CountQuery" query that returns a number of rows in a given table:
public class CountQuery extends IndirectQuery { protected Class objectClass; public CountQuery(Class objectClass) { this.objectClass = objectClass; } protected Query createReplacementQuery(EntityResolver resolver) { DbEntity entity = resolver.lookupDbEntity(objectClass); if (entity == null) { throw new CayenneRuntimeException( "No entity is mapped for java class: " + objectClass.getName()); } String sql = "SELECT #result('count(*)' 'int' 'C') FROM " + entity.getName(); SQLTemplate replacement = new SQLTemplate(entity, sql); replacement.setFetchingDataRows(true); return replacement; } }
Now you can run the query like that:
CountQuery query = new CountQuery(Artist.class); DataContext context = DataContext.createDataContext(); Map row = (Map) context.performQuery(query).get(0); System.out.println("Count: " + row.get("C"));
For other real-life examples of indirect queries take a look at the source code of the following Cayenne queries: QueryChain, ObjectIdQuery, RelationshipQuery, NamedQuery.
All standard queries can be subclassed, overriding some of their methods. For instance overriding route and/or createSQLAction would allow to implement custom callbacks at different points of query lifecycle.