JDOQL Single-String

JDOQL queries can be defined in a single string form. This string has to follow the following pattern

SELECT [UNIQUE] [<result>] [INTO <result-class>]
        [FROM <candidate-class> [EXCLUDE SUBCLASSES]]
        [WHERE <filter>]
        [VARIABLES <variable declarations>]
        [PARAMETERS <parameter declarations>]
        [<import declarations>]
        [GROUP BY <grouping>]
        [ORDER BY <ordering>]
        [RANGE <start>, <end>]>

The "keywords" in the query are shown in UPPER CASE but can be in UPPER or lower case (but not MiXeD case).

Lets give an example of a query using this syntax

SELECT UNIQUE FROM mydomain.Employee ORDER BY departmentNumber

so we form the parts of the query as before, yet here we just specify it all in a single call.



Explicit Parameters

With a query you can pass values into the query as parameters. If you declare the parameters when defining the query then these are explicit parameters, so you set the type of the parameter, and when you pass the value in it has to be of that type.

Here's a simple example for finding the elements of a class with a field below a particular threshold level. Here we pass in the threshold value ( limit )

Query query = pm.newQuery(
    "SELECT FROM mydomain.Product WHERE price < limit PARAMETERS double limit");
List results = (List)query.execute(150.00);

For completeness, the class is shown here

class Product
{
    double price;
    ...
}


Implicit Parameters

With a query you can pass values into the query as parameters. If you don't declare the parameters when defining the query but instead prefix identifiers in the query with : (colon) then these are implicit parameters.

Let's repeat the previous query but this time using implicit parameters.

Query query = pm.newQuery(
    "SELECT FROM mydomain.Product WHERE price < :limit");
List results = (List)query.execute(150.00);


Variables

In JDOQL you can connect two parts of a query using something known as a variable. For example, we want to retrieve all objects with a collection that contains a particular element, and where the element has a particular field value. We define a query like this

Query query = pm.newQuery("SELECT FROM mydomain.Supplier " +
    "WHERE products.contains(prod) && prod.name == \"Beans\" VARIABLES mydomain.Product prod");

So we have a variable in our query called "prod" that connects the two parts. You can declare your variables if you want to define the type like here (explicit variables), or you can leave them for the query compilation to determine (implicit variables)



setCandidates()

If you don't want to query instances in the datastore but instead query a collection of candidate instances, you can do this by setting the candidates, like this

Query query = pm.newQuery("SELECT FROM mydomain.Product WHERE value < 50");
query.setCandidates(myCandidates);
List<Product> results = (List<Product>)query.execute();

This will process the query in-memory.