2. Getting started with Querydsl

Instead of a general Getting started guide we provide integration guides for the main backends of Querydsl.

2.1. Querying JDO sources

Querydsl defines a general statically typed syntax for querying on top of persisted domain model data. JDO and JPA are the primary integration technologies for Querydsl. This guide describes how to use Querydsl in combination with JDO. Support for JDO is in beta phase and still to be considered experimental.

2.1.1. Maven integration

Add the following dependency to your Maven project and make sure that the Maven 2 repo of Mysema Source (http://source.mysema.com/maven2/releases) is accessible from your POM if the version cannot yet be found in other public Maven repos :

<http://xslthl.sf.net:tag><dependency></http://xslthl.sf.net:tag>
  <http://xslthl.sf.net:tag><groupId></http://xslthl.sf.net:tag>com.mysema.querydsl<http://xslthl.sf.net:tag></groupId></http://xslthl.sf.net:tag>
  <http://xslthl.sf.net:tag><artifactId></http://xslthl.sf.net:tag>querydsl-jdoql<http://xslthl.sf.net:tag></artifactId></http://xslthl.sf.net:tag>
  <http://xslthl.sf.net:tag><version></http://xslthl.sf.net:tag>0.4.0<http://xslthl.sf.net:tag></version></http://xslthl.sf.net:tag>
<http://xslthl.sf.net:tag></dependency></http://xslthl.sf.net:tag>

And now, configure the Maven APT plugin which generates the query types used by Querydsl :

<http://xslthl.sf.net:tag><project></http://xslthl.sf.net:tag>
  <http://xslthl.sf.net:tag><build></http://xslthl.sf.net:tag>
    <http://xslthl.sf.net:tag><plugins></http://xslthl.sf.net:tag>
      ...
      <http://xslthl.sf.net:tag><plugin></http://xslthl.sf.net:tag>
        <http://xslthl.sf.net:tag><groupId></http://xslthl.sf.net:tag>com.mysema.maven<http://xslthl.sf.net:tag></groupId></http://xslthl.sf.net:tag>
        <http://xslthl.sf.net:tag><artifactId></http://xslthl.sf.net:tag>maven-apt-plugin<http://xslthl.sf.net:tag></artifactId></http://xslthl.sf.net:tag>
        <http://xslthl.sf.net:tag><version></http://xslthl.sf.net:tag>0.2.0<http://xslthl.sf.net:tag></version></http://xslthl.sf.net:tag>
        <http://xslthl.sf.net:tag><executions></http://xslthl.sf.net:tag>
          <http://xslthl.sf.net:tag><execution></http://xslthl.sf.net:tag>
            <http://xslthl.sf.net:tag><goals></http://xslthl.sf.net:tag>
              <http://xslthl.sf.net:tag><goal></http://xslthl.sf.net:tag>process<http://xslthl.sf.net:tag></goal></http://xslthl.sf.net:tag>
            <http://xslthl.sf.net:tag></goals></http://xslthl.sf.net:tag>
            <http://xslthl.sf.net:tag><configuration></http://xslthl.sf.net:tag>
              <http://xslthl.sf.net:tag><outputDirectory></http://xslthl.sf.net:tag>target/generated-sources/java<http://xslthl.sf.net:tag></outputDirectory></http://xslthl.sf.net:tag>
              <http://xslthl.sf.net:tag><processor></http://xslthl.sf.net:tag>com.mysema.query.jdoql.apt.JDOAnnotationProcessor<http://xslthl.sf.net:tag></processor></http://xslthl.sf.net:tag>
            <http://xslthl.sf.net:tag></configuration></http://xslthl.sf.net:tag>
          <http://xslthl.sf.net:tag></execution></http://xslthl.sf.net:tag>
        <http://xslthl.sf.net:tag></executions></http://xslthl.sf.net:tag>
      <http://xslthl.sf.net:tag></plugin></http://xslthl.sf.net:tag>
    ...
    <http://xslthl.sf.net:tag></plugins></http://xslthl.sf.net:tag>
  <http://xslthl.sf.net:tag></build></http://xslthl.sf.net:tag>
<http://xslthl.sf.net:tag></project></http://xslthl.sf.net:tag>

The JDOAnnotationProcessor finds domain types annotated with the javax.jdo.annotations.PersistenceCapable annotation and generates Querydsl query types for them. Run mvn eclipse:eclipse or clean install and you will get your Query types generated into target/generated-sources/java.

Now you are able to construct JDOQL query instances and instances of the query domain model.

2.1.2. Using query types

To create queries with Querydsl you need to instantiate variables and Query implementations. We will start with the variables.

Let's assume that your project has the following domain type :

@PersistenceCapable
public class Customer {
  private String firstName;
  private String lastName;
  
  public String getFirstName(){
    return firstName;
  }
  
  public String getLastName(){
    return lastName;
  }
  
  public void setFirstName(String fn){
    firstName = fn;
  }
  
  public void setLastName(String ln)[
    lastName = ln;
  }
}

Querydsl will generate a query type with the simple name QCustomer into the same package as Customer. QCustomer can be used as a statically typed variable in Querydsl queries as a representative for the Customer type.

QCustomer has a default instance variable which can be accessed as a static field :

QCustomer customer = QCustomer.customer;

Alternatively you can define your own Customer variables like this :

QCustomer customer = new QCustomer("myCustomer");

QCustomer reflects all the properties of the original type Customer as public fields. The firstName field can be accessed like this

customer.firstName;

The generated Querydsl query types are based on a builtin expression type system. The Querydsl expression archetypes are presented in more detailed on this page : [Querydsl expressions].

2.1.3. Querying with JDOQL

For the JDOQL-module JDOQLQueryImpl is the main Query implementation. It is instantiated like this :

PersistenceManager pm;
...
JDOQLQuery query = new JDOQLQueryImpl (pm);

To retrieve the customer with the first name Bob you would construct a query like this :

QCustomer customer = QCustomer.customer;
JDOQLQuery query = new JDOQLQueryImpl (pm);
Customer bob = query.from(customer)
  .where(customer.firstName.eq("Bob"))
  .uniqueResult(customer);
query.close();

The from call defines the query source, the where part defines the filter and uniqueResult defines the projection and tells Querydsl to return a single element. Easy, right?

To create a query with multiple sources you just use the JDOQLQuery interface like this :

query.from(customer, company);    

And to use multiple filters use it like this

query.from(customer)
    .where(customer.firstName.eq("Bob"), customer.lastName.eq("Wilson"));   

Or like this

query.form(customer)
    .where(customer.firstName.eq("Bob").and(customer.lastName.eq("Wilson")));

2.1.4. Ordering

The syntax for declaring ordering is

 
query.from(customer)
    .orderBy(customer.lastName.asc(), customer.firstName.desc())
    .list(customer);

2.1.5. Grouping

Grouping can be done in the following form

 
query.from(customer)
    .groupBy(customer.lastName)
    .list(customer.lastName);

2.1.6. Subqueries

Subqueries in the JDOQL module are just special projections of the JDOQLQuery interface. To create a subquery you create a JDOQLQuery instance, define the query parameters via from, where etc and use uniqueExpr or listExpr to create a subquery, which is just a type-safe Querydsl expression for the query. uniqueExpr is used for a unique result and listExpr for a list result.

query().from(department)
    .where(department.employees.size().eq(
        query().from(d).uniqueExpr(AggregationFunctions.max(d.employees.size()))
     )).list(department);  

represents the following native JDOQL query

SELECT this FROM com.mysema.query.jdoql.models.company.Department
WHERE this.employees.size() == 
(SELECT max(d.employees.size()) FROM com.mysema.query.jdoql.models.company.Department d)

Another example

query().from(employee)
    .where(employee.weeklyhours.gt(
        query().from(employee.department.employees, e)
        .where(e.manager.eq(employee.manager))
        .uniqueExpr(AggregationFunctions.avg(e.weeklyhours))
    )).list(employee);

which represents the following native JDOQL query

SELECT this FROM com.mysema.query.jdoql.models.company.Employee 
WHERE this.weeklyhours > 
(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)

2.1.7. Aggregate functions

Aggregate functions are available as static methods in the com.mysema.query.functions.AggreationFunctions class.