![JAR search and dependency download from the Maven repository](/logo.png)
com.avaje.ebean.Query Maven / Gradle / Ivy
package com.avaje.ebean;
import org.jetbrains.annotations.Nullable;
import javax.persistence.NonUniqueResultException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Object relational query for finding a List, Set, Map or single entity bean.
*
* Example: Create the query using the API.
*
*
*
{@code
*
* List orderList =
* ebeanServer.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
*
* {@code
*
* String oql =
* +" fetch customer "
* +" fetch details "
* +" where customer.name like :custName and orderDate > :minOrderDate "
* +" order by customer.id, id desc "
* +" limit 50 ";
*
* Query query = ebeanServer.createQuery(Order.class, oql);
* query.setParameter("custName", "Rob%");
* query.setParameter("minOrderDate", lastWeek);
*
* List orderList = query.findList();
* ...
* }
*
* Example: Using a named query called "with.cust.and.details"
*
* {@code
*
* Query query = ebeanServer.createNamedQuery(Order.class,"with.cust.and.details");
* query.setParameter("custName", "Rob%");
* query.setParameter("minOrderDate", lastWeek);
*
* List orderList = query.findList();
* ...
* }
* AutoTune
*
* Ebean has built in support for "AutoTune". 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 AutoTune 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.
*
* {@code
* [ select [ ( * | {fetch properties} ) ] ]
* [ fetch {path} [ ( * | {fetch properties} ) ] ]
* [ where {predicates} ]
* [ order by {order by properties} ]
* [ limit {max rows} [ offset {first row} ] ]
* }
*
* SELECT [ ( * | {fetch properties} ) ]
*
*
* With the select you can specify a list of properties to fetch.
*
*
* FETCH {path} [ ( * | {fetch properties} ) ]
*
*
* With the fetch you specify the associated property to fetch and populate. The
* path is a OneToOne, ManyToOne, OneToMany or ManyToMany property.
*
*
* 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 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.
*
* {@code
*
* select (shipDate, status)
*
* }
*
* Find orders with a named bind variable (that will need to be bound via
* {@link Query#setParameter(String, Object)}).
*
* {@code
*
* 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.
*
* {@code
*
* 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.
*
* {@code
*
* fetch customer (name)
* fetch customer.shippingAddress
* fetch details
* fetch details.product (sku, name)
*
* }
*
* @param the type of Entity bean this query will fetch.
*/
public interface Query {
/**
* Return the RawSql that was set to use for this query.
*/
RawSql getRawSql();
/**
* Set RawSql to use for this query.
*/
Query setRawSql(RawSql rawSql);
/**
* Perform an 'As of' query using history tables to return the object graph
* as of a time in the past.
*
* To perform this query the DB must have underlying history tables.
*
*
* @param asOf the date time in the past at which you want to view the data
*/
Query asOf(Timestamp asOf);
/**
* Execute the query against the draft set of tables.
*/
Query asDraft();
/**
* Cancel the query execution if supported by the underlying database and
* driver.
*
* This must be called from a different thread to the query executor.
*
*/
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.
*
*/
Query copy();
/**
* Specify the PersistenceContextScope to use for this query.
*
* When this is not set the 'default' configured on {@link com.avaje.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
* is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
*
* Note that the same persistence Context is used for subsequent lazy loading and query join queries.
*
* Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for
* queries executed as #findIterate, #findEach, #findEachWhile.
*
* @param scope The scope to use for this query and subsequent lazy loading.
*/
Query setPersistenceContextScope(PersistenceContextScope scope);
/**
* Return the ExpressionFactory used by this query.
*/
ExpressionFactory getExpressionFactory();
/**
* Returns true if this query was tuned by autoTune.
*/
boolean isAutoTuned();
/**
* Explicitly specify whether to use AutoTune for this query.
*
* If you do not call this method on a query the "Implicit AutoTune mode" is
* used to determine if AutoTune should be used for a given query.
*
*
* AutoTune 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 AutoTune will not remove them.
*
*/
Query setAutoTune(boolean autoTune);
/**
* Set the default lazy loading batch size to use.
*
* When lazy loading is invoked on beans loaded by this query then this sets the
* batch size used to load those beans.
*
* @param lazyLoadBatchSize the number of beans to lazy load in a single batch
*/
Query setLazyLoadBatchSize(int lazyLoadBatchSize);
/**
* Execute the query including soft deleted rows.
*
* This means that Ebean will not add any predicates to the query for filtering out
* soft deleted rows. You can still add your own predicates for the deleted properties
* and effectively you have full control over the query to include or exclude soft deleted
* rows as needed for a given use case.
*
*/
Query setIncludeSoftDeletes();
/**
* Disable read auditing for this query.
*
* This is intended to be used when the query is not a user initiated query and instead
* part of the internal processing in an application to load a cache or document store etc.
* In these cases we don't want the query to be part of read auditing.
*
*/
Query setDisableReadAuditing();
/**
* Specify the properties to fetch on the root level entity bean in comma delimited format.
*
* The Id property is automatically included in the properties to fetch unless setDistinct(true)
* is set on the query.
*
*
* Use {@link #fetch(String, String)} to specify specific properties to fetch
* on other non-root level paths of the object graph.
*
* {@code
*
* List customers =
* ebeanServer.find(Customer.class)
* // Only fetch the customer id, name and status.
* // This is described as a "Partial Object"
* .select("name, status")
* .where.ilike("name", "rob%")
* .findList();
*
* }
*
* @param fetchProperties the properties to fetch for this bean (* = all properties).
*/
Query select(String fetchProperties);
/**
* Specify a path to fetch eagerly including specific properties.
*
* Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
* not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
* will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
*
* {@code
*
* // query orders...
* List orders =
* ebeanServer.find(Order.class)
* // fetch the customer...
* // ... getting the customers name and phone number
* .fetch("customer", "name, phoneNumber")
*
* // ... also fetch the customers billing address (* = all properties)
* .fetch("customer.billingAddress", "*")
* .findList();
* }
*
* If columns is null or "*" then all columns/properties for that path are fetched.
*
* {@code
*
* // fetch customers (their id, name and status)
* List customers =
* ebeanServer.find(Customer.class)
* .select("name, status")
* .fetch("contacts", "firstName,lastName,email")
* .findList();
*
* }
*
* @param path the property path we wish to fetch eagerly.
* @param fetchProperties properties of the associated bean that you want to include in the
* fetch (* means all properties, null also means all properties).
*/
Query fetch(String path, String fetchProperties);
/**
* Fetch the path and properties using a "query join" (separate SQL query).
*
* This is the same as:
*
* {@code
*
* fetch(path, fetchProperties, new FetchConfig().query())
*
* }
*
* This would be used instead of a fetch() when we use a separate SQL query to fetch this
* part of the object graph rather than a SQL join.
*
*
* We might typically get a performance benefit when the path to fetch is a OneToMany
* or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
* is high.
*
*
* @param path the property path we wish to fetch eagerly.
* @param fetchProperties properties of the associated bean that you want to include in the
* fetch (* means all properties, null also means all properties).
*/
Query fetchQuery(String path, String fetchProperties);
/**
* Fetch the path and properties lazily (via batch lazy loading).
*
* This is the same as:
*
* {@code
*
* fetch(path, fetchProperties, new FetchConfig().lazy())
*
* }
*
* The reason for using fetchLazy() is to either:
*
*
* - Control/tune what is fetched as part of lazy loading
* - Make use of the L2 cache, build this part of the graph from L2 cache
*
*
* @param path the property path we wish to fetch lazily.
* @param fetchProperties properties of the associated bean that you want to include in the
* fetch (* means all properties, null also means all properties).
*/
Query fetchLazy(String path, String fetchProperties);
/**
* Additionally specify a FetchConfig to use a separate query or lazy loading
* to load this path.
* {@code
*
* // fetch customers (their id, name and status)
* List customers =
* ebeanServer.find(Customer.class)
* .select("name, status")
* .fetch("contacts", "firstName,lastName,email", new FetchConfig().lazy(10))
* .findList();
*
* }
*
* @param path the property path we wish to fetch eagerly.
*/
Query fetch(String path, String fetchProperties, FetchConfig fetchConfig);
/**
* Specify a path to fetch eagerly including all its properties.
*
* Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
* not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
* will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
*
* {@code
*
* // fetch customers (their id, name and status)
* List customers =
* ebeanServer.find(Customer.class)
* // eager fetch the contacts
* .fetch("contacts")
* .findList();
*
* }
*
* @param path the property path we wish to fetch eagerly.
*/
Query fetch(String path);
/**
* Fetch the path eagerly using a "query join" (separate SQL query).
*
* This is the same as:
*
* {@code
*
* fetch(path, new FetchConfig().query())
*
* }
*
* This would be used instead of a fetch() when we use a separate SQL query to fetch this
* part of the object graph rather than a SQL join.
*
*
* We might typically get a performance benefit when the path to fetch is a OneToMany
* or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
* is high.
*
*
* @param path the property path we wish to fetch eagerly
*/
Query fetchQuery(String path);
/**
* Fetch the path lazily (via batch lazy loading).
*
* This is the same as:
*
* {@code
*
* fetch(path, new FetchConfig().lazy())
*
* }
*
* The reason for using fetchLazy() is to either:
*
*
* - Control/tune what is fetched as part of lazy loading
* - Make use of the L2 cache, build this part of the graph from L2 cache
*
*
* @param path the property path we wish to fetch lazily.
*/
Query fetchLazy(String path);
/**
* Additionally specify a JoinConfig to specify a "query join" and or define
* the lazy loading query.
* {@code
*
* // fetch customers (their id, name and status)
* List customers =
* ebeanServer.find(Customer.class)
* // lazy fetch contacts with a batch size of 100
* .fetch("contacts", new FetchConfig().lazy(100))
* .findList();
*
* }
*/
Query fetch(String path, FetchConfig fetchConfig);
/**
* Apply the path properties replacing the select and fetch clauses.
*
* This is typically used when the FetchPath is applied to both the query and the JSON output.
*
*/
Query apply(FetchPath fetchPath);
/**
* 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)
*/
List