3. General usage

3.1. Expressions

3.1.1. Custom expressions

The com.mysema.query.support.Expressions class is a static factory class for Querydsl expression construction.

The following expression

QPerson person = QPerson.person; 	    
person.firstName.startsWith("P");

could be constructed like this if Q-types wouldn't be available

Path<Person> person = Expressions.path(Person.class, "person");
Path<String> personFirstName = Expressions.path(String.class, person, "firstName");
Constant<String> constant = Expressions.constant("P");
Expressions.predicate(Ops.STARTS_WITH, personFirstName, constant);

Path instances represent variables and properties, Constants are constants, Operations are operations and TemplateExpression instances can be used to express expressions as String templates.

3.1.2. Custom projections

For custom projections the com.mysema.query.types.Projections class offers a set of factory methods for Bean, constructor, Tuple and other projections.

3.1.3. Inheritance in Querydsl types

To avoid a generic signature in Querydsl query types the type hierarchies are flattened. The result is that all generated query types are direct subclasses of com.mysema.query.types.path.EntityPathBase or com.mysema.query.types.path.BeanPath and cannot be directly cast to their Querydsl supertypes.

Instead of a direct Java cast, the supertype reference is accessible via the _super field. A _super-field is available in all generated query types with a single supertype :

// from Account
QAccount extends EntityPathBase<Account>{
    // ...
}

// from BankAccount extends Account
QBankAccount extends EntityPathBase<BankAccount>{

    public final QAccount _super = new QAccount(this);
    
    // ...
}            

To cast from a supertype to a subtype you can use the as-method of the EntityPathBase class :

QAccount account = new QAccount("account");
QBankAccount bankAccount = account.as(QBankAccount.class);    

3.1.4. Constructor projections

Querydsl provides the possibility to use constructor invocations in projections. To use a constructor in a query projection, you need to annotate it with the QueryProjection annotation :

class CustomerDTO {

  @QueryProjection
  public CustomerDTO(long id, String name){
     ...
  }

}

And then you can use it like this in the query

QCustomer customer = QCustomer.customer;
JPQLQuery query = new HibernateQuery(session);
List<CustomerDTO> dtos = qry.from(customer).list(new QCustomerDTO(customer.id, customer.name));     

While the example is Hibernate specific, this feature is available in all modules.

If the type with the QueryProjection annotation is not an annotated entity type, you can use the constructor projection like in the example, but if the annotated type would be an entity type, then the constructor projection would need to be created via a call to the static create method of the query type :

@Entity
class Customer {

  @QueryProjection
  public Customer(long id, String name){
     ...
  }

}
QCustomer customer = QCustomer.customer;
JPQLQuery query = new HibernateQuery(session);
List<Customer> dtos = qry.from(customer).list(QCustomer.create(customer.id, customer.name));   

Alternatively, if code generation is not an option, you can create a constructor projection like this :

List<Customer> dtos = qry.from(customer)
    .list(ConstructorExpression.create(Customer.class, customer.id, customer.name));   

3.1.5. Complex boolean expressions

To construct complex boolean expressions, use the BooleanBuilder class. It implements Predicate and can be used in cascaded form :

public List<Customer> getCustomer(String... names){
    QCustomer customer = QCustomer.customer;    
    HibernateQuery qry = new HibernateQuery(session).from(customer);    
    BooleanBuilder builder = new BoolenBuilder();
    for (String name : names){
        builder.or(customer.name.eq(name));
    }
    qry.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ...  
    return qry.list(customer);
}

3.1.6. Case expressions

To construct case-when-then-else expressions use the CaseBuilder class like this :

    
QCustomer customer = QCustomer.customer;    
Expression<String> cases = new CaseBuilder()
    .when(customer.annualSpending.gt(10000)).then("Premier")
    .when(customer.annualSpending.gt(5000)).then("Gold")
    .when(customer.annualSpending.gt(2000)).then("Silver")
    .otherwise("Bronze");
// The cases expression can now be used in a projection or condition        

For case expressions with equals-operations use the following simpler form instead :

    
QCustomer customer = QCustomer.customer;    
Expression<String> cases = customer.annualSpending
    .when(10000).then("Premier")
    .when(5000).then("Gold")
    .when(2000).then("Silver")
    .otherwise("Bronze");
// The cases expression can now be used in a projection or condition        

Case expressions are not yet supported in JDOQL.

3.1.7. Dynamic path usage

For dynamic path generation the PathBuilder class can be used. It extends EntityPathBase and can be used as an alternative to class generation and alias-usage for path generation.

String property :

PathBuilder<User> entityPath = new PathBuilder<User>(User.class, "entity");
// fully generic access
entityPath.get("userName");
// .. or with supplied type
entityPath.get("userName", String.class);
// .. and correct signature
entityPath.getString("userName").lower();

List property with component type :

entityPath.getList("list", String.class).get(0);

Using a component expression type :

entityPath.getList("list", String.class, StringPath.class).get(0).lower();

Map property with key and value type :

entityPath.getMap("map", String.class, String.class).get("key");

Using a component expression type :

entityPath.getMap("map", String.class, String.class, StringPath.class).get("key").lower();