All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebean.Query Maven / Gradle / Ivy

There is a newer version: 2.8.1
Show newest version
/**
 * Copyright (C) 2009 Authors
 * 
 * This file is part of Ebean.
 * 
 * Ebean is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *  
 * Ebean is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Ebean; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA  
 */
package com.avaje.ebean;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.avaje.ebean.config.ServerConfig;

/**
 * Object relational query for finding a List, Set, Map or single entity bean.
 * 

* Example: Create the query using the API. *

* *
 * List<Order> orderList = 
 *   Ebean.find(Order.class)
 *     .fetch("customer")
 *     .fetch("details")
 *     .where()
 *       .like("customer.name","rob%")
 *       .gt("orderDate",lastWeek)
 *     .orderBy("customer.id, id desc")
 *     .setMaxRows(50)
 *     .findList();
 *   
 * ...
 * 
* *

* Example: The same query using the query language *

* *
 * String oql = 
 *   	"  find  order "
 *   	+" fetch customer "
 *   	+" fetch details "
 *   	+" where customer.name like :custName and orderDate > :minOrderDate "
 *   	+" order by customer.id, id desc "
 *   	+" limit 50 ";
 *   
 * Query<Order> query = Ebean.createQuery(Order.class, oql);
 * query.setParameter("custName", "Rob%");
 * query.setParameter("minOrderDate", lastWeek);
 *   
 * List<Order> orderList = query.findList();
 * ...
 * 
* *

* Example: Using a named query called "with.cust.and.details" *

* *
 * Query<Order> query = Ebean.createNamedQuery(Order.class,"with.cust.and.details");
 * query.setParameter("custName", "Rob%");
 * query.setParameter("minOrderDate", lastWeek);
 *   
 * List<Order> orderList = query.findList();
 * ...
 * 
* *

Autofetch

*

* Ebean has built in support for "Autofetch". This is a mechanism where a query * can be automatically tuned based on profiling information that is collected. *

*

* This is effectively the same as automatically using select() and fetch() to * build a query that will fetch all the data required by the application and no * more. *

*

* It is expected that Autofetch will be the default approach for many queries * in a system. It is possibly not as useful where the result of a query is sent * to a remote client or where there is some requirement for "Read Consistency" * guarantees. *

* *

Query Language

*

* Partial Objects *

*

* The find and fetch clauses support specifying a list of * properties to fetch. This results in objects that are "partially populated". * If you try to get a property that was not populated a "lazy loading" query * will automatically fire and load the rest of the properties of the bean (This * is very similar behaviour as a reference object being "lazy loaded"). *

*

* Partial objects can be saved just like fully populated objects. If you do * this you should remember to include the "Version" property in the * initial fetch. If you do not include a version property then optimistic * concurrency checking will occur but only include the fetched properties. * Refer to "ALL Properties/Columns" mode of Optimistic Concurrency checking. *

* *
 * [ find  {bean type} [ ( * | {fetch properties} ) ] ]
 * [ fetch {associated bean} [ ( * | {fetch properties} ) ] ]
 * [ where {predicates} ]
 * [ order by {order by properties} ]
 * [ limit {max rows} [ offset {first row} ] ]
 * 
* *

* FIND {bean type} [ ( * | {fetch properties} ) ] *

*

* With the find you specify the type of beans to fetch. You can optionally * specify a list of properties to fetch. If you do not specify a list of * properties ALL the properties for those beans are fetched. *

*

* In object graph terms the find clause specifies the type of bean at * the root level and the fetch clauses specify the paths of the object * graph to populate. *

*

* FETCH {associated property} [ ( * | {fetch * properties} ) ] *

*

* With the fetch you specify the associated property to fetch and populate. The * associated property is a OneToOnem, ManyToOne, OneToMany or ManyToMany * property. When the query is executed Ebean will fetch the associated data. *

*

* For fetch of a path we can optionally specify a list of properties to fetch. * If you do not specify a list of properties ALL the properties for that bean * type are fetched. *

*

* WHERE {list of predicates} *

*

* The list of predicates which are joined by AND OR NOT ( and ). They can * include named (or positioned) bind parameters. These parameters will need to * be bound by {@link Query#setParameter(String, Object)}. *

*

* ORDER BY {order by properties} *

*

* The list of properties to order the result. You can include ASC (ascending) * and DESC (descending) in the order by clause. *

*

* LIMIT {max rows} [ OFFSET {first row} ] *

*

* The limit offset specifies the max rows and first row to fetch. The offset is * optional. *

*

Examples of Ebean's Query Language

*

* Find orders fetching all its properties *

* *
 * find order
 * 
* *

* Find orders fetching all its properties *

* *
 * find order (*)
 * 
* *

* Find orders fetching its id, shipDate and status properties. Note that the id * property is always fetched even if it is not included in the list of fetch * properties. *

* *
 * find order (shipDate, status)
 * 
* *

* Find orders with a named bind variable (that will need to be bound via * {@link Query#setParameter(String, Object)}). *

* *
 * find order
 * where customer.name like :custLike
 * 
* *

* Find orders and also fetch the customer with a named bind parameter. This * will fetch and populate both the order and customer objects. *

* *
 * find  order
 * fetch customer
 * where customer.id = :custId
 * 
* *

* Find orders and also fetch the customer, customer shippingAddress, order * details and related product. Note that customer and product objects will be * "Partial Objects" with only some of their properties populated. The customer * objects will have their id, name and shipping address populated. The product * objects (associated with each order detail) will have their id, sku and name * populated. *

* *
 * find  order
 * fetch customer (name)
 * fetch customer.shippingAddress
 * fetch details
 * fetch details.product (sku, name)
 * 
* *

Early parsing of the Query

*

* When you get a Query object from a named query, the query statement has * already been parsed. You can then add to that query (add fetch paths, add to * the where clause) or override some of its settings (override the order by * clause, first rows, max rows). *

*

* The thought is that you can use named queries as a 'starting point' and then * modify the query to suit specific needs. *

*

Building the Where clause

*

* You can add to the where clause using Expression objects or a simple String. * Note that the ExpressionList has methods to add most of the common * expressions that you will need. *

    *
  • where(String addToWhereClause)
  • *
  • where().add(Expression expression)
  • *
  • where().eq(propertyName, value).like(propertyName , value)...
  • *
*

*

* The full WHERE clause is constructed by appending together *

  • original query where clause (Named query or query.setQuery(String oql))
  • *
  • clauses added via query.where(String addToWhereClause)
  • *
  • clauses added by Expression objects
  • *

    *

    * The above is the order that these are clauses are appended to give the full * WHERE clause. *

    *

    Design Goal

    *

    * This query language is NOT designed to be a replacement for SQL. It is * designed to be a simple way to describe the "Object Graph" you want Ebean to * build for you. Each find/fetch represents a node in that "Object Graph" which * makes it easy to define for each node which properties you want to fetch. *

    *

    * Once you hit the limits of this language such as wanting aggregate functions * (sum, average, min etc) or recursive queries etc you use SQL. Ebean's goal is * to make it as easy as possible to use your own SQL to populate entity beans. * Refer to {@link RawSql} . *

    * * @param * the type of Entity bean this query will fetch. */ public interface Query extends Serializable { /** * How this query should use (or not) the Lucene Index if one is defined for * the bean type. */ public enum UseIndex { NO, DEFAULT, YES_IDS, YES_OBJECTS } /** * The type of query result. */ public enum Type { /** * Find by Id or unique returning a single bean. */ BEAN, /** * Find returning a List. */ LIST, /** * Find returning a Set. */ SET, /** * Find returning a Map. */ MAP, /** * Find the Id's. */ ID_LIST, /** * Find rowCount. */ ROWCOUNT, /** * A subquery used as part of a where clause. */ SUBQUERY } /** * Explicitly specify how this query should use a Lucene Index if one is * defined for this bean type. */ public Query setUseIndex(UseIndex useIndex); /** * Return the setting for how this query should use a Lucene Index if one is * defined for this bean type. */ public UseIndex getUseIndex(); /** * Return the type of query (List, Set, Map, Bean, rowCount etc). */ public Type getType(); /** * Return the RawSql that was set to use for this query. */ public RawSql getRawSql(); /** * Set RawSql to use for this query. */ public Query setRawSql(RawSql rawSql); /** * Cancel the query execution if supported by the underlying database and * driver. *

    * This must be called from a different thread to the query executor. *

    */ public void cancel(); /** * Return a copy of the query. *

    * This is so that you can use a Query as a "prototype" for creating other * query instances. You could create a Query with various where expressions * and use that as a "prototype" - using this copy() method to create a new * instance that you can then add other expressions then execute. *

    */ public Query copy(); /** * Return the ExpressionFactory used by this query. */ public ExpressionFactory getExpressionFactory(); /** * Returns true if this query was tuned by autoFetch. */ public boolean isAutofetchTuned(); /** * Explicitly specify whether to use Autofetch for this query. *

    * If you do not call this method on a query the "Implicit Autofetch mode" * is used to determine if Autofetch should be used for a given query. *

    *

    * Autofetch can add additional fetch paths to the query and specify which * properties are included for each path. If you have explicitly defined * some fetch paths Autofetch will not remove. *

    */ public Query setAutofetch(boolean autofetch); /** * Deprecated in favour of {@link EbeanServer#createQuery(Class, String)}. *

    * Set the query using the query language. *

    * * @deprecated */ public Query setQuery(String oql); /** * Explicitly set a comma delimited list of the properties to fetch on the * 'main' entity bean (aka partial object). Note that '*' means all * properties. * *
         * Query<Customer> query = Ebean.createQuery(Customer.class);
         * 
         * // Only fetch the customer id, name and status.
         * // This is described as a "Partial Object"
         * query.select("name, status");
         * query.where("lower(name) like :custname").setParameter("custname", "rob%");
         * 
         * List<Customer> customerList = query.findList();
         * 
    * * @param fetchProperties * the properties to fetch for this bean (* = all properties). */ public Query select(String fetchProperties); /** * Specify a path to fetch with its specific properties to include * (aka partial object). *

    * When you specify a join this means that property (associated bean(s)) * will be fetched and populated. If you specify "*" then all the properties * of the associated bean will be fetched and populated. You can specify a * comma delimited list of the properties of that associated bean which * means that only those properties are fetched and populated resulting in a * "Partial Object" - a bean that only has some of its properties populated. *

    * *
         * // query orders...
         * Query<Order> query = Ebean.createQuery(Order.class);
         * 
         * // fetch the customer... 
         * // ... getting the customer's name and phone number
         * query.fetch("customer", "name, phNumber");
         * 
         * // ... also fetch the customers billing address (* = all properties)
         * query.fetch("customer.billingAddress", "*");
         * 
    * *

    * If columns is null or "*" then all columns/properties for that path are * fetched. *

    * *
         * // fetch customers (their id, name and status)
         * Query<Customer> query = Ebean.createQuery(Customer.class);
         * 
         * // only fetch some of the properties of the customers
         * query.select("name, status");
         * List<Customer> list = query.findList();
         * 
    * * @param path * the path of an associated (1-1,1-M,M-1,M-M) bean. * @param fetchProperties * properties of the associated bean that you want to include in * the fetch (* means all properties, null also means all * properties). */ public Query fetch(String path, String fetchProperties); /** * Same as {@link #fetch(String, String)}. *

    * This will eventually be deprecated in favour of the matching "fetch" * method. *

    * @deprecated Deprecated in favour of {@link #fetch(String, String)} */ public Query join(String assocProperty, String fetchProperties); /** * Additionally specify a FetchConfig to use a separate query or lazy * loading to load this path. */ public Query fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig); /** * Additionally specify a JoinConfig to specify a "query join" and or define * the lazy loading query. * * @deprecated Deprecated in favour of {@link #fetch(String, String, FetchConfig)} */ public Query join(String assocProperty, String fetchProperties, JoinConfig joinConfig); /** * Specify a path to load including all its properties. *

    * The same as {@link #fetch(String, String)} with the fetchProperties as * "*". *

    * * @param path * the property of an associated (1-1,1-M,M-1,M-M) bean. */ public Query fetch(String path); /** * Deprecated in favour of {@link #fetch(String)} * * @deprecated in favour of {@link #fetch(String)} */ public Query join(String path); /** * Additionally specify a JoinConfig to specify a "query join" and or define * the lazy loading query. */ public Query fetch(String path, FetchConfig joinConfig); /** * Deprecated in favour of {@link #fetch(String, FetchConfig)} * * @deprecated in favour of {@link #fetch(String, FetchConfig)} */ public Query join(String path, JoinConfig joinConfig); /** * Execute the query returning the list of Id's. *

    * This query will execute against the EbeanServer that was used to create * it. *

    * * @see EbeanServer#findIds(Query, Transaction) */ public List findIds(); /** * Execute the query iterating over the results. *

    * Remember that with {@link QueryIterator} you must call {@link QueryIterator#close()} * when you have finished iterating the results (typically in a finally block). *

    *

    * This query will execute against the EbeanServer that was used to create * it. *

    */ public QueryIterator findIterate(); /** * Execute the query using callbacks to a visitor to process the resulting * beans one at a time. *

    * Similar to findIterate() this query method does not require all the * result beans to be all held in memory at once and as such is useful for * processing large queries. *

    * *
         * 
         * Query<Customer> query = server.find(Customer.class)
         *  .fetch("contacts", new FetchConfig().query(2))
         *  .where().gt("id", 0)
         *  .orderBy("id")
         *  .setMaxRows(2);
         * 
         * query.findVisit(new QueryResultVisitor<Customer>() {
         * 
         *     public boolean accept(Customer customer) {
         *         // do something with customer
         *         System.out.println("-- visit " + customer);
         *         return true;
         *     }
         * });
         * 
    * * @param visitor * the visitor used to process the queried beans. */ public void findVisit(QueryResultVisitor visitor); /** * Execute the query returning the list of objects. *

    * This query will execute against the EbeanServer that was used to create * it. *

    * * @see EbeanServer#findList(Query, Transaction) */ public List findList(); /** * Execute the query returning the set of objects. *

    * This query will execute against the EbeanServer that was used to create * it. *

    * * @see EbeanServer#findSet(Query, Transaction) */ public Set findSet(); /** * Execute the query returning a map of the objects. *

    * This query will execute against the EbeanServer that was used to create * it. *

    *

    * You can use setMapKey() so specify the property values to be used as keys * on the map. If one is not specified then the id property is used. *

    * *
         * Query<Product> query = Ebean.createQuery(Product.class);
         * query.setMapKey("sku");
         * Map<?, Product> map = query.findMap();
         * 
    * * @see EbeanServer#findMap(Query, Transaction) */ public Map findMap(); /** * Return a typed map specifying the key property and type. */ public Map findMap(String keyProperty, Class keyType); /** * Execute the query returning either a single bean or null (if no matching * bean is found). *

    * If more than 1 row is found for this query then a PersistenceException is * thrown. *

    *

    * This is useful when your predicates dictate that your query should only * return 0 or 1 results. *

    * *
         * // assuming the sku of products is unique...
         * Product product =
         *     Ebean.find(Product.class)
         *         .where("sku = ?")
         *         .set(1, "aa113")
         *         .findUnique();
         * ...
         * 
    * *

    * It is also useful with finding objects by their id when you want to * specify further join information. *

    * *
         * // Fetch order 1 and additionally fetch join its order details...
         * Order order = 
         *     Ebean.find(Order.class)
         *       .setId(1)
         *       .fetch("details")
         *       .findUnique();
         *       
         * List<OrderDetail> details = order.getDetails();
         * ...
         * 
    */ public T findUnique(); /** * Return the count of entities this query should return. *

    * This is the number of 'top level' or 'root level' entities. *

    */ public int findRowCount(); /** * Execute find row count query in a background thread. *

    * This returns a Future object which can be used to cancel, check the * execution status (isDone etc) and get the value (with or without a * timeout). *

    * * @return a Future object for the row count query */ public FutureRowCount findFutureRowCount(); /** * Execute find Id's query in a background thread. *

    * This returns a Future object which can be used to cancel, check the * execution status (isDone etc) and get the value (with or without a * timeout). *

    * * @return a Future object for the list of Id's */ public FutureIds findFutureIds(); /** * Execute find list query in a background thread. *

    * This returns a Future object which can be used to cancel, check the * execution status (isDone etc) and get the value (with or without a * timeout). *

    * * @return a Future object for the list result of the query */ public FutureList findFutureList(); /** * Return a PagingList for this query. *

    * This can be used to break up a query into multiple queries to fetch the * data a page at a time. *

    *

    * This typically works by using a query per page and setting * {@link Query#setFirstRow(int)} and and {@link Query#setMaxRows(int)} on * the query. This usually would translate into SQL that uses limit offset, * rownum or row_number function to limit the result set. *

    * * @param pageSize * the number of beans fetched per Page * */ public PagingList findPagingList(int pageSize); /** * Set a named bind parameter. Named parameters have a colon to prefix the * name. * *
         * // a query with a named parameter
         * String oql = "find order where status = :orderStatus";
         * 
         * Query<Order> query = Ebean.createQuery(Order.class, oql);
         * 
         * // bind the named parameter
         * query.bind("orderStatus", OrderStatus.NEW);
         * List<Order> list = query.findList();
         * 
    * * @param name * the parameter name * @param value * the parameter value */ public Query setParameter(String name, Object value); /** * Set an ordered bind parameter according to its position. Note that the * position starts at 1 to be consistent with JDBC PreparedStatement. You * need to set a parameter value for each ? you have in the query. * *
         * // a query with a positioned parameter
         * String oql = "where status = ? order by id desc";
         * 
         * Query<Order> query = Ebean.createQuery(Order.class, oql);
         * 
         * // bind the parameter
         * query.setParameter(1, OrderStatus.NEW);
         * 
         * List<Order> list = query.findList();
         * 
    * * @param position * the parameter bind position starting from 1 (not 0) * @param value * the parameter bind value. */ public Query setParameter(int position, Object value); /** * Set a listener to process the query on a row by row basis. *

    * Use this when you want to process a large query and do not want to hold * the entire query result in memory. *

    *

    * It this case the rows are not loaded into the persistence context and * instead are processed by the query listener. *

    * *
         * QueryListener<Order> listener = ...;
         *   
         * Query<Order> query  = Ebean.createQuery(Order.class);
         *   
         * // set the listener that will process each order one at a time
         * query.setListener(listener);
         *   
         * // execute the query. Note that the returned
         * // list (emptyList) will be empty ...
         * List<Order> emtyList = query.findList();
         * 
    */ public Query setListener(QueryListener queryListener); /** * Set the Id value to query. This is used with findUnique(). *

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

    * *
         * Query<Order> query = Ebean.createQuery(Order.class);
         * Order order = query.setId(1).join("details").findUnique();
         * List<OrderDetail> details = order.getDetails();
         * ...
         * 
    */ public Query setId(Object id); /** * Add additional clause(s) to the where clause. *

    * This typically contains named parameters which will need to be set via * {@link #setParameter(String, Object)}. *

    * *
         * Query<Order> query = Ebean.createQuery(Order.class, "top");
         * ...
         * if (...) {
         *   query.where("status = :status and lower(customer.name) like :custName");
         *   query.setParameter("status", Order.NEW);
         *   query.setParameter("custName", "rob%");
         * }
         * 
    * *

    * Internally the addToWhereClause string is processed by removing named * parameters (replacing them with ?) and by converting logical property * names to database column names (with table alias). The rest of the string * is left as is and it is completely acceptable and expected for the * addToWhereClause string to include sql functions and columns. *

    * * @param addToWhereClause * the clause to append to the where clause which typically * contains named parameters. * @return The query object */ public Query where(String addToWhereClause); /** * Add a single Expression to the where clause returning the query. * *
         * List<Order> newOrders = 
         *     Ebean.find(Order.class)
         * 		.where().eq("status", Order.NEW)
         * 		.findList();
         * ...
         * 
    */ public Query where(Expression expression); /** * Add Expressions to the where clause with the ability to chain on the * ExpressionList. You can use this for adding multiple expressions to the * where clause. * *
         * Query<Order> query = Ebean.createQuery(Order.class, "top");
         * ...
         * if (...) {
         *   query.where()
         *     .eq("status", Order.NEW)
         *     .ilike("customer.name","rob%");
         * }
         * 
    * * @see Expr * @return The ExpressionList for adding expressions to. */ public ExpressionList where(); /** * This applies a filter on the 'many' property list rather than the root * level objects. *

    * Typically you will use this in a scenario where the cardinality is high * on the 'many' property you wish to join to. Say you want to fetch * customers and their associated orders... but instead of getting all the * orders for each customer you only want to get the new orders they placed * since last week. In this case you can use filterMany() to filter the * orders. *

    * *
         * 
         * List<Customer> list = Ebean.find(Customer.class)
         * // .fetch("orders", new FetchConfig().lazy())
         *         // .fetch("orders", new FetchConfig().query())
         *         .fetch("orders").where().ilike("name", "rob%").filterMany("orders").eq("status", Order.Status.NEW).gt(
         *                 "orderDate", lastWeek).findList();
         * 
         * 
    * *

    * Please note you have to be careful that you add expressions to the * correct expression list - as there is one for the 'root level' and one * for each filterMany that you have. *

    * * @param propertyName * the name of the many property that you want to have a filter * on. * * @return the expression list that you add filter expressions for the many * to. */ public ExpressionList filterMany(String propertyName); /** * Add Expressions to the Having clause return the ExpressionList. *

    * Currently only beans based on raw sql will use the having clause. *

    *

    * Note that this returns the ExpressionList (so you can add multiple * expressions to the query in a fluent API way). *

    * * @see Expr * @return The ExpressionList for adding more expressions to. */ public ExpressionList having(); /** * Add additional clause(s) to the having clause. *

    * This typically contains named parameters which will need to be set via * {@link #setParameter(String, Object)}. *

    * *
         * Query<ReportOrder> query = Ebean.createQuery(ReportOrder.class);
         * ...
         * if (...) {
         *   query.having("score > :min");
         *   query.setParameter("min", 1);
         * }
         * 
    * * @param addToHavingClause * the clause to append to the having clause which typically * contains named parameters. * @return The query object */ public Query having(String addToHavingClause); /** * Add an expression to the having clause returning the query. *

    * Currently only beans based on raw sql will use the having clause. *

    *

    * This is similar to {@link #having()} except it returns the query rather * than the ExpressionList. This is useful when you want to further specify * something on the query. *

    * * @param addExpressionToHaving * the expression to add to the having clause. * @return the Query object */ public Query having(Expression addExpressionToHaving); /** * Set the order by clause replacing the existing order by clause if there * is one. *

    * This follows SQL syntax using commas between each property with the * optional asc and desc keywords representing ascending and descending * order respectively. *

    *

    * This is EXACTLY the same as {@link #order(String)}. *

    */ public Query orderBy(String orderByClause); /** * Set the order by clause replacing the existing order by clause if there * is one. *

    * This follows SQL syntax using commas between each property with the * optional asc and desc keywords representing ascending and descending * order respectively. *

    *

    * This is EXACTLY the same as {@link #orderBy(String)}. *

    */ public Query order(String orderByClause); /** * Return the OrderBy so that you can append an ascending or descending * property to the order by clause. *

    * This will never return a null. If no order by clause exists then an * 'empty' OrderBy object is returned. *

    *

    * This is EXACTLY the same as {@link #orderBy()}. *

    */ public OrderBy order(); /** * Return the OrderBy so that you can append an ascending or descending * property to the order by clause. *

    * This will never return a null. If no order by clause exists then an * 'empty' OrderBy object is returned. *

    *

    * This is EXACTLY the same as {@link #order()}. *

    */ public OrderBy orderBy(); /** * Set an OrderBy object to replace any existing OrderBy clause. *

    * This is EXACTLY the same as {@link #setOrderBy(OrderBy)}. *

    */ public Query setOrder(OrderBy orderBy); /** * Set an OrderBy object to replace any existing OrderBy clause. *

    * This is EXACTLY the same as {@link #setOrder(OrderBy)}. *

    */ public Query setOrderBy(OrderBy orderBy); /** * Set whether this query uses DISTINCT. */ public Query setDistinct(boolean isDistinct); /** * Set this to true and the beans and collections returned will be plain * classes rather than Ebean generated dynamic subclasses etc. *

    * This is *ONLY* relevant when you are not using enhancement (and using * dynamic subclasses instead). *

    *

    * Alternatively you can globally set the mode using ebean.vanillaMode=true * in ebean.properties or {@link ServerConfig#setVanillaMode(boolean)}. *

    * * @see ServerConfig#setVanillaMode(boolean) * @see ServerConfig#setVanillaRefMode(boolean) */ public Query setVanillaMode(boolean vanillaMode); /** * Return the first row value. */ public int getFirstRow(); /** * Set the first row to return for this query. * * @param firstRow */ public Query setFirstRow(int firstRow); /** * Return the max rows for this query. */ public int getMaxRows(); /** * Set the maximum number of rows to return in the query. * * @param maxRows * the maximum number of rows to return in the query. */ public Query setMaxRows(int maxRows); /** * Set the rows after which fetching should continue in a background thread. * * @param backgroundFetchAfter */ public Query setBackgroundFetchAfter(int backgroundFetchAfter); /** * Set the property to use as keys for a map. *

    * If no property is set then the id property is used. *

    * *
         * // Assuming sku is unique for products...
         *    
         * Query<Product> query = Ebean.createQuery(Product.class);
         *   
         * // use sku for keys...
         * query.setMapKey("sku");
         *   
         * Map<?,Product> productMap = query.findMap();
         * ...
         * 
    * * @param mapKey * the property to use as keys for a map. */ public Query setMapKey(String mapKey); /** * Set this to true to use the bean cache. *

    * If the query result is in cache then by default this same instance is * returned. In this sense it should be treated as a read only object graph. *

    */ public Query setUseCache(boolean useBeanCache); /** * Set this to true to use the query cache. */ public Query setUseQueryCache(boolean useQueryCache); /** * When set to true when you want the returned beans to be read only. */ public Query setReadOnly(boolean readOnly); /** * When set to true all the beans from this query are loaded into the bean * cache. */ public Query setLoadBeanCache(boolean loadBeanCache); /** * Set a timeout on this query. *

    * This will typically result in a call to setQueryTimeout() on a * preparedStatement. If the timeout occurs an exception will be thrown - * this will be a SQLException wrapped up in a PersistenceException. *

    * * @param secs * the query timeout limit in seconds. Zero means there is no * limit. */ public Query setTimeout(int secs); /** * A hint which for JDBC translates to the Statement.fetchSize(). *

    * Gives the JDBC driver a hint as to the number of rows that should be * fetched from the database when more rows are needed for ResultSet. *

    */ public Query setBufferFetchSizeHint(int fetchSize); /** * Return the sql that was generated for executing this query. *

    * This is only available after the query has been executed and provided * only for informational purposes. *

    */ public String getGeneratedSql(); }