JDO 3.2 JDOQLTypedQuery

JDO 3.2 is now standardising what we initially developed as a DataNucleus extension for JDO querying, namely typesafe queries. In DataNucleus upto and including v4.1 it was referred to as JDOQL Typesafe Query, and in JDO 3.2 (DataNucleus v4.2+) it is called JDOQLTypedQuery. Here we present some examples, the same examples as a previous blog post about the original DataNucleus extension but now updated to the JDOQLTypedQuery API.

In these examples we have a class Product. Consequently we have a “query” class autogenerated – QProduct. Here is the QProduct class

public class QProduct extends PersistableExpressionImpl implements PersistableExpression
{
    public static QProduct candidate() {...} // candidate "this"
    public static QProduct candidate(String name) {...}
    public static QProduct parameter(String name) {...}
    public static QProduct variable(String name) {...}
    public NumericExpression id;
    public StringExpression name;
    public NumericExpression value;
    ...
}

So, as you can see we have access to the persistable fields/properties of Product by way of public fields in its query class. Now on to some examples

Filter only
Here we select all Products that have a value less than 40.0

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
List<Product> results = tq.filter(QProduct.candidate().value.lt(40.0))
    .executeList();

Filter + Order
Here we select all Products that have a value less than 40.0 and ordering by their name

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
List<Product> results = tq.filter(cand.value.lt(40.0))
    .orderBy(cand.name.asc())
    .executeList();

Filter + Order + Result
Here we select the product name and product value for all Products that have a value less than 40.0 , ordering by their name

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
List results = tq.filter(cand.value.lt(40.0)).orderBy(cand.name.asc())
    .result(true, cand.name, cand.value)
    .executeResultList();

Filter with Methods
Here we select all Products that have a value less than 40.0 and name starting with “Wal”, and ordering by their name

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
List<Product> results = 
    tq.filter(cand.value.lt(40.0).and(cand.name.startsWith("Wal")))
    .executeList();

Filter, using Parameters
Here we select all Products that have a value less than 40.0, using a parameter

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate()
List<Product> results = 
    tq.filter(cand.value.lt(tq.doubleParameter("param1")))
    .setParameter("param1", 40.0)
    .executeList();

Order + Range
Here we select Products, ordering by the name and restrict to the first two

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
List<Product> results = tq.orderBy(cand.name.asc()).range(0,2)
    .executeList();

Filter with Variable
Here we select Inventory (which has a collection of Products) that contain a Product with a particular name

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(Inventory.class);
QInventory cand = QInventory.candidate();
QProduct var = QProduct.variable("var");
List<Product> results = 
    tq.filter(cand.products.contains(var).and(var.name.startsWith("Wal")))
    .executeList();

Filter with Subquery
Here we select Products with a value less than the average value of any Product

JDOQLtypedQuery tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
JDOQLTypedSubquery tqsub = tq.subquery(Product.class, "p");
QProduct candsub = QProduct.candidate("p");
List<Product> results = 
    tq.filter(cand.value.lt(tqsub.select(candsub.value.avg())))
    .executeList();

As you can see from the above queries we have no hard-coded class or field names, providing better refactorability. We can obviously make use of all JDOQL supported methods in the above queries, and define parameters and variables just like in the standard (string-based) JDOQL API.

It should be noted that this JDOQL facility is much more elegant and requires less code than the equivalent queries using JPA “Criteria”.

Advertisements
This entry was posted in Criteria, DataNucleus, JDO, JDOQL, JPA, JPQL, Typesafe. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s