Title: Parameterized Queries
SelectQuery objects can be rather complex. They may contain long qualifiers and lots of tuning parameters. Parameterized Queries feature addresses reusability of complex queries. With this feature, for each group of queries that differ only in the values used in the qualifier, a developer may create a single shared "prototype" or "template" query, and use it later as a factory for other queries. All settings configured in the prototype object will be passed to the final queries. Qualifier of the prototype query may use named parameters that are substituted for real values when a final query is created from the prototype.
"Prototype" queries are normally created in CayenneModeler and stored in the DataMap XML file. "Queries Stored in DataMap" chapter describes how to use such templates. This chapter shows how to create them on the spot using the API calls. |
Building a prototype query using Expression.fromString(..):
import org.apache.cayenne.exp.Expression; import org.apache.cayenne.query.SelectQuery; ... // create a qualifier with two named parameters: "pname" and "aname" Expression qual = Expression.fromString("paintingTitle = $pname or toArtist.artistName = $aname"); // build a query prototype of a query - simply another select query SelectQuery proto = new SelectQuery(Painting.class, qual); proto.setDistinct(true);
Same example but using ExpressionFactory:
import java.util.*; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.exp.ExpressionParameter; import org.apache.cayenne.query.SelectQuery; ... // create a qualifier with two named parameters: // "pname" and "aname" List list = new ArrayList(); list.add(ExpressionFactory.matchExp("paintingTitle", new ExpressionParameter("pname"))); list.add(ExpressionFactory.matchExp("toArtist.artistName", new ExpressionParameter("aname"))); Expression qual = ExpressionFactory.joinExp(Expression.OR, list); // build a query prototype of a query - simply another select query SelectQuery proto = new SelectQuery(Painting.class, qual); proto.setDistinct(true);
Prototype built in the example above can be used to create other queries. Relevalnt API is:
Example of using queryWithParameters is shown below:
import java.util.Map; import java.util.HashMap; import org.apache.cayenne.query.SelectQuery; ... SelectQuery proto = ... // this was built in the example above // create a query Map params1 = new HashMap(); params1.put("aname", "Dali"); SelectQuery query1 = proto.queryWithParameters(params1); // further customize returned query // without affecting the prototype query1.setFetchLimit(100); ... // create another query with a different set of parameters Map params2 = new HashMap(); params2.put("aname", "Monet"); params2.put("pname", "The Beach at Trouville"); SelectQuery query2 = proto.queryWithParameters(params2); ...