Interface IQueryBean<T,R extends IQueryBean<T,R>>

Type Parameters:
T - the entity bean type (normal entity bean type e.g. Customer)
R - the specific query bean type (e.g. QCustomer)
All Superinterfaces:
io.ebean.QueryBuilder<R,T>, io.ebean.QueryBuilderProjection<R,T>
All Known Implementing Classes:
QueryBean

public interface IQueryBean<T,R extends IQueryBean<T,R>> extends io.ebean.QueryBuilder<R,T>
Query bean for strongly typed query construction and execution.

For each entity bean querybean-generator generates a query bean that implements QueryBean.

Example - usage of QCustomer



  Date fiveDaysAgo = ...

  List<Customer> customers =
      new QCustomer()
        .name.ilike("rob")
        .status.equalTo(Customer.Status.GOOD)
        .registered.after(fiveDaysAgo)
        .contacts.email.endsWith("@foo.com")
        .orderBy()
          .name.asc()
          .registered.desc()
        .findList();

 

Resulting SQL where



   where lower(t0.name) like ? and t0.status = ? and t0.registered > ? and u1.email like ?
   order by t0.name, t0.registered desc;

   --bind(rob,GOOD,Mon Jul 27 12:05:37 NZST 2015,%@foo.com)

 
  • Method Summary

    Modifier and Type
    Method
    Description
    add(io.ebean.Expression expression)
    Add an expression to the WHERE or HAVING clause.
    and()
    Begin a list of expressions added by 'AND'.
    io.ebean.FetchGroup<T>
    Return the fetch group.
    distinctOn(TQProperty<R,?>... properties)
    Set DISTINCT ON properties.
    End AND junction - synonym for endJunction().
    End a list of expressions added by 'OR'.
    End NOT junction - synonym for endJunction().
    End OR junction - synonym for endJunction().
    exists(io.ebean.Query<?> subQuery)
    Add EXISTS sub-query predicate.
    exists(String sqlSubQuery, Object... bindValues)
    EXISTS using a SQL SubQuery.
    io.ebean.ExpressionList<T>
    Return the expression list that has been built for this query.
    Start adding expressions to the having clause when using @Aggregation properties.
    io.ebean.ExpressionList<T>
    Return the underlying having clause to typically when using dynamic aggregation formula.
    inTuples(io.ebean.InTuples inTuples)
    In expression using multiple columns.
    not()
    Begin a list of expressions added by NOT.
    notExists(io.ebean.Query<?> subQuery)
    Add NOT EXISTS sub-query predicate.
    notExists(String sqlSubQuery, Object... bindValues)
    Not EXISTS using a SQL SubQuery.
    or()
    Begin a list of expressions added by 'OR'.
    Deprecated, for removal: This API element is subject to removal in a future version.
    migrate to orderBy().
    order(String orderByClause)
    Deprecated, for removal: This API element is subject to removal in a future version.
    migrate to QueryBuilder.orderBy(String)
    Marker that can be used to indicate that the order by clause is defined after this.
    io.ebean.Query<T>
    Return the underlying query.
    raw(String rawExpression)
    Add raw expression with no parameters.
    raw(String rawExpression, Object bindValue)
    Add raw expression with a single parameter.
    raw(String rawExpression, Object... bindValues)
    Add raw expression with an array of parameters.
    rawOrEmpty(String raw, Collection<?> values)
    Only add the raw expression if the values is not null or empty.
    select(io.ebean.Query.Property<?>... properties)
    Specify the properties to be loaded on the 'main' root level entity bean also allowing for functions to be used like StdOperators.max(Query.Property).
    select(TQProperty<R,?>... properties)
    Specify the properties to be loaded on the 'main' root level entity bean.
    Set the Id value to query.
    setIdIn(Object... ids)
    Set a list of Id values to match.
    Set a collection of Id values to match.
    setProfileLocation(io.ebean.ProfileLocation profileLocation)
    Set the profile location of this query.
    Add expression after this to the WHERE expression list.

    Methods inherited from interface io.ebean.QueryBuilder

    alias, also, alsoIf, asDto, asOf, asUpdate, copy, delete, exists, findCount, findEach, findEach, findEachWhile, findFutureCount, findFutureIds, findFutureList, findFutureMap, findIds, findIterate, findList, findMap, findOne, findOneOrEmpty, findPagedList, findSet, findSingleAttribute, findSingleAttributeList, findSingleAttributeOrEmpty, findSingleAttributeSet, findStream, findVersions, findVersionsBetween, forUpdate, forUpdateNoWait, forUpdateSkipLocked, getBeanType, getGeneratedSql, orderBy, orderById, setAllowLoadErrors, setAutoTune, setBaseTable, setBeanCacheMode, setBufferFetchSizeHint, setCountDistinct, setDisableLazyLoading, setDistinct, setFirstRow, setHint, setIncludeSoftDeletes, setLabel, setLazyLoadBatchSize, setMapKey, setMaxRows, setOrderBy, setPaging, setPersistenceContextScope, setRawSql, setTimeout, setUnmodifiable, setUseCache, setUseQueryCache, setUseQueryCache, usingConnection, usingDatabase, usingMaster, usingTransaction, validate, withLock, withLock

    Methods inherited from interface io.ebean.QueryBuilderProjection

    apply, distinctOn, fetch, fetch, fetch, fetch, fetchCache, fetchCache, fetchLazy, fetchLazy, fetchQuery, fetchQuery, select, select
  • Method Details

    • query

      io.ebean.Query<T> query()
      Return the underlying query.

      Generally it is not expected that you will need to do this but typically use the find methods available on this 'root query bean' instance like findList().

    • buildFetchGroup

      io.ebean.FetchGroup<T> buildFetchGroup()
      Return the fetch group.
    • distinctOn

      R distinctOn(TQProperty<R,?>... properties)
      Set DISTINCT ON properties. This is a Postgres only SQL feature.
      Parameters:
      properties - The properties to include in the DISTINCT ON clause.
    • select

      R select(TQProperty<R,?>... properties)
      Specify the properties to be loaded on the 'main' root level entity bean.

      The resulting entities with be "partially loaded" aka partial objects.

      Alternatively we can use a QueryBuilderProjection.select(FetchGroup) to specify all properties to load on all parts of the graph.

      
      
         // alias for the customer properties in select()
         QCustomer cust = QCustomer.alias();
      
         // alias for the contact properties in contacts.fetch()
         QContact contact = QContact.alias();
      
         List<Customer> customers =
           new QCustomer()
             // specify the parts of the graph we want to load
             .select(cust.id, cust.name)
             .contacts.fetch(contact.firstName, contact.lastName, contact.email)
      
             // predicates
             .id.gt(1)
             .findList();
      
       
      Parameters:
      properties - the list of properties to fetch
    • select

      R select(io.ebean.Query.Property<?>... properties)
      Specify the properties to be loaded on the 'main' root level entity bean also allowing for functions to be used like StdOperators.max(Query.Property).
      Parameters:
      properties - the list of properties to fetch
    • add

      R add(io.ebean.Expression expression)
      Add an expression to the WHERE or HAVING clause.
    • exists

      R exists(io.ebean.Query<?> subQuery)
      Add EXISTS sub-query predicate.
    • notExists

      R notExists(io.ebean.Query<?> subQuery)
      Add NOT EXISTS sub-query predicate.
    • exists

      R exists(String sqlSubQuery, Object... bindValues)
      EXISTS using a SQL SubQuery.
      Parameters:
      sqlSubQuery - The SQL SubQuery
      bindValues - Optional bind values if the SubQuery uses ? bind values.
    • notExists

      R notExists(String sqlSubQuery, Object... bindValues)
      Not EXISTS using a SQL SubQuery.
      Parameters:
      sqlSubQuery - The SQL SubQuery
      bindValues - Optional bind values if the SubQuery uses ? bind values.
    • setId

      R setId(Object id)
      Set the Id value to query. This is used with findOne().

      You can use this to have further control over the query. For example adding fetch joins.

      
      
       Order order =
         new QOrder()
           .setId(1)
           .fetch("details")
           .findOne();
      
       // the order details were eagerly fetched
       List<OrderDetail> details = order.getDetails();
      
       
    • setIdIn

      R setIdIn(Object... ids)
      Set a list of Id values to match.

      
      
       List<Order> orders =
         new QOrder()
           .setIdIn(42, 43, 44)
           .findList();
      
       
    • setIdIn

      R setIdIn(Collection<?> ids)
      Set a collection of Id values to match.

      
      
       Collection<?> ids = ...
      
       List<Order> orders =
         new QOrder()
           .setIdIn(ids)
           .findList();
      
       
    • raw

      R raw(String rawExpression)
      Add raw expression with no parameters.

      When properties in the clause are fully qualified as table-column names then they are not translated. logical property name names (not fully qualified) will still be translated to their physical name.

      
      
         raw("orderQty < shipQty")
      
       

      Subquery example:

      
      
         .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
      
       
    • raw

      R raw(String rawExpression, Object... bindValues)
      Add raw expression with an array of parameters.

      The raw expression should contain the same number of ? as there are parameters.

      When properties in the clause are fully qualified as table-column names then they are not translated. logical property name names (not fully qualified) will still be translated to their physical name.

    • rawOrEmpty

      R rawOrEmpty(String raw, Collection<?> values)
      Only add the raw expression if the values is not null or empty.

      This is a pure convenience expression to make it nicer to deal with the pattern where we use raw() expression with a subquery and only want to add the subquery predicate when the collection of values is not empty.

      Without inOrEmpty()

      
      
         QCustomer query = new QCustomer() // add some predicates
           .status.equalTo(Status.NEW);
      
         // common pattern - we can use rawOrEmpty() instead
         if (orderIds != null && !orderIds.isEmpty()) {
           query.raw("t0.customer_id in (select o.customer_id from orders o where o.id in (?1))", orderIds);
         }
      
         query.findList();
      
       

      Using rawOrEmpty()

      Note that in the example below we use the ?1 bind parameter to get "parameter expansion" for each element in the collection.
      
      
         new QCustomer()
           .status.equalTo(Status.NEW)
           // only add the expression if orderIds is not empty
           .rawOrEmpty("t0.customer_id in (select o.customer_id from orders o where o.id in (?1))", orderIds);
           .findList();
      
       

      Postgres ANY

      With Postgres we would often use the SQL ANY expression and array parameter binding rather than IN.
      
      
         new QCustomer()
           .status.equalTo(Status.NEW)
           .rawOrEmpty("t0.customer_id in (select o.customer_id from orders o where o.id = any(?))", orderIds);
           .findList();
      
       

      Note that we need to cast the Postgres array for UUID types like:

      
      
         " ... = any(?::uuid[])"
      
       
      Parameters:
      raw - The raw expression that is typically a subquery
      values - The values which is typically a list or set of id values.
    • raw

      R raw(String rawExpression, Object bindValue)
      Add raw expression with a single parameter.

      The raw expression should contain a single ? at the location of the parameter.

      When properties in the clause are fully qualified as table-column names then they are not translated. logical property name names (not fully qualified) will still be translated to their physical name.

      Example:

      
      
         // use a database function
         raw("add_days(orderDate, 10) < ?", someDate)
      
       

      Subquery example:

      
      
         .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
      
       
    • inTuples

      R inTuples(io.ebean.InTuples inTuples)
      In expression using multiple columns.
    • orderBy

      R orderBy()
      Marker that can be used to indicate that the order by clause is defined after this.

      Example: order by customer name, order date

      
         List<Order> orders =
                new QOrder()
                  .customer.name.ilike("rob")
                  .orderBy()
                    .customer.name.asc()
                    .orderDate.asc()
                  .findList();
      
       
    • order

      @Deprecated(since="13.19", forRemoval=true) R order()
      Deprecated, for removal: This API element is subject to removal in a future version.
      migrate to orderBy().
    • order

      @Deprecated(since="13.19", forRemoval=true) R order(String orderByClause)
      Deprecated, for removal: This API element is subject to removal in a future version.
      migrate to QueryBuilder.orderBy(String)
    • or

      R or()
      Begin a list of expressions added by 'OR'.

      Use endOr() or endJunction() to stop added to OR and 'pop' to the parent expression list.

      Example

      This example uses an 'OR' expression list with an inner 'AND' expression list.

      
      
          List<Customer> customers =
                new QCustomer()
                  .status.equalTo(Customer.Status.GOOD)
                  .or()
                    .id.greaterThan(1000)
                    .and()
                      .name.startsWith("super")
                      .registered.after(fiveDaysAgo)
                    .endAnd()
                  .endOr()
                  .orderBy().id.desc()
                  .findList();
      
       

      Resulting SQL where clause

      sql
      
          where t0.status = ?  and (t0.id > ?  or (t0.name like ?  and t0.registered > ? ) )
          order by t0.id desc;
      
          --bind(GOOD,1000,super%,Wed Jul 22 00:00:00 NZST 2015)
      
       
    • and

      R and()
      Begin a list of expressions added by 'AND'.

      Use endAnd() or endJunction() to stop added to AND and 'pop' to the parent expression list.

      Note that typically the AND expression is only used inside an outer 'OR' expression. This is because the top level expression list defaults to an 'AND' expression list.

      Example

      This example uses an 'OR' expression list with an inner 'AND' expression list.

      
      
          List<Customer> customers =
                new QCustomer()
                  .status.equalTo(Customer.Status.GOOD)
                  .or() // OUTER 'OR'
                    .id.greaterThan(1000)
                    .and()  // NESTED 'AND' expression list
                      .name.startsWith("super")
                      .registered.after(fiveDaysAgo)
                      .endAnd()
                    .endOr()
                  .orderBy().id.desc()
                  .findList();
      
       

      Resulting SQL where clause

      sql
      
          where t0.status = ?  and (t0.id > ?  or (t0.name like ?  and t0.registered > ? ) )
          order by t0.id desc;
      
          --bind(GOOD,1000,super%,Wed Jul 22 00:00:00 NZST 2015)
      
       
    • not

      R not()
      Begin a list of expressions added by NOT.

      Use endNot() or endJunction() to stop added to NOT and 'pop' to the parent expression list.

    • endJunction

      R endJunction()
      End a list of expressions added by 'OR'.
    • endOr

      R endOr()
      End OR junction - synonym for endJunction().
    • endAnd

      R endAnd()
      End AND junction - synonym for endJunction().
    • endNot

      R endNot()
      End NOT junction - synonym for endJunction().
    • where

      R where()
      Add expression after this to the WHERE expression list.

      For queries against the normal database (not the doc store) this has no effect.

      This is intended for use with Document Store / ElasticSearch where expressions can be put into either the "query" section or the "filter" section of the query. Full text expressions like MATCH are in the "query" section but many expression can be in either - expressions after the where() are put into the "filter" section which means that they don't add to the relevance and are also cache-able.

    • getExpressionList

      io.ebean.ExpressionList<T> getExpressionList()
      Return the expression list that has been built for this query.
    • having

      R having()
      Start adding expressions to the having clause when using @Aggregation properties.
      
      
         new QMachineUse()
         // where ...
         .date.inRange(fromDate, toDate)
      
         .having()
         .sumHours.greaterThan(1)
         .findList()
      
         // The sumHours property uses @Aggregation
         // e.g. @Aggregation("sum(hours)")
      
       
    • havingClause

      io.ebean.ExpressionList<T> havingClause()
      Return the underlying having clause to typically when using dynamic aggregation formula.

      Note that after this we no longer have the query bean so typically we use this right at the end of the query.

      
      
        // sum(distanceKms) ... is a "dynamic formula"
        // so we use havingClause() for it like:
      
        List<MachineUse> machineUse =
      
          new QMachineUse()
            .select("machine, sum(fuelUsed), sum(distanceKms)")
      
            // where ...
            .date.greaterThan(LocalDate.now().minusDays(7))
      
            .havingClause()
              .gt("sum(distanceKms)", 2)
              .findList();
      
       
    • setProfileLocation

      R setProfileLocation(io.ebean.ProfileLocation profileLocation)
      Set the profile location of this query. This is used to relate query execution metrics back to a location like a specific line of code.