11.9. Single-String JDOQL
Prev | Chapter 11. Query | Next

## 11.9. Single-String JDOQL

It is often convenient to represent an entire JDOQL query as a single string. JDO defines a single-string query form that encompasses all parts of a query: the unique flag, result string, result class, filter, parameters, variables, imports, grouping, ordering, and range.

| Note
Single-string JDOQL is new in JDO 2. Its format is subject to change prior to the final JDO 2 specification. In addition to standard single-string JDOQL support, Kodo uses the single-string format to implement JDOQL subquery support, covered in Section 13.3, “JDOQL Subqueries”.

We present the grammar for single-string JDOQL queries below. Clauses in square brackets are optional. Clauses in angle brackets are required, and represent portions of the `Query` API.

    select [unique] [<result>] [into <result class>]
        [from <candidate class> [exclude subclasses]]
        [where <filter>]
        [parameters <parameter declarations>]
        [variables <variable declarations>]
        [imports <import declarations>]
        [group by <grouping>]
        [order by <ordering>]
        [range <start>, <end>]

The `PersistenceManager` has a factory method designed specifically for constructing a query from a single argument (in this case, a JDOQL string):

    public Query newQuery (Object query);

In each code block below, we create and execute a standard JDOQL query, then demonstrate the same process using the single-string format. As you'll see, translating any query into single-string form is just a matter of plugging the corresponding strings into the grammar above.

    Query query = pm.newQuery ();
    query.setResult ("distinct title");
    query.setClass (Magazine.class);
    query.setFilter ("price < :p");
    query.setRange (10, 20);
    Collection results = (Collection) query.execute (new Double (10.0));

    Query query = pm.newQuery ("select distinct title from org.mag.Magazine "
        + "where price < :p range 10, 20");
    Collection results = (Collection) query.execute (new Double (10.0));

    Query query = pm.newQuery ();
    query.setUnique (true);
    query.setCandidates (pm.getExtent (Magazine.class, false));
    query.setFilter ("title == 'JDJ'");
    Magazine mag = (Magazine) query.execute ();

    Query query = pm.newQuery ("select unique from org.mag.Magazine "
        + "exclude subclasses where title == 'JDJ'");
    Magazine mag = (Magazine) query.execute ();

    Query query = pm.newQuery ();
    query.setResult ("publisher.name as pub, avg(price) as price");
    query.setResultClass (org.mag.pub.PubPrice.class);
    query.setClass (Magazine.class);
    query.setGrouping ("publisher having avg(price) < :p");
    query.setOrdering ("publisher.name ascending");
    Collection results = (Collection) query.execute (new Double (10.0));

    Query query = pm.newQuery ("select publisher.name as pub, avg(price) as price "
        + "into org.mag.pub.PubPrice from org.mag.Magazine "
        + "group by publisher having avg(price) < :p "
        + "order by publisher.name ascending");
    Collection results = (Collection) query.execute (new Double (10.0));

On a final note, single-string queries are mutable. You can construct a single-string query as in the examples above, then change the result string, filter, or any other part of the query through the standard `Query` APIs. This is especially useful for temporary properties like the result range.

Prev | Up | Next
11.8. Result Class | Home | 11.10. Named Queries