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

io.ebean.Query Maven / Gradle / Ivy

There is a newer version: 15.8.1
Show newest version
package io.ebean;

import org.jspecify.annotations.NullMarked;

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

* Example: Create the query using the API. * *

{@code
 *
 * List orderList = DB.find(Order.class)
 *     .where()
 *       .like("customer.name","rob%")
 *       .gt("orderDate",lastWeek)
 *     .order("customer.id, id desc")
 *     .setMaxRows(50)
 *     .findList();
 *
 * }
*

* Example: The same query using the query language * *

{@code
 *
 * String oql =
 *   	+" where customer.name like :custName and orderDate > :minOrderDate "
 *   	+" order by customer.id, id desc "
 *   	+" limit 50 ";
 *
 * List orderList = DB.createQuery(Order.class, oql)
 *   .setParameter("custName", "Rob%")
 *   .setParameter("minOrderDate", lastWeek)
 *   .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. */ @NullMarked public interface Query extends CancelableQuery, QueryBuilder, T> { /** * The lock type (strength) to use with query FOR UPDATE row locking. */ enum LockType { /** * The default lock type being either UPDATE or NO_KEY_UPDATE based on * PlatformConfig.forUpdateNoKey configuration (Postgres option). */ DEFAULT, /** * FOR UPDATE. */ UPDATE, /** * FOR NO KEY UPDATE (Postgres only). */ NO_KEY_UPDATE, /** * FOR SHARE (Postgres only). */ SHARE, /** * FOR KEY SHARE (Postgres only). */ KEY_SHARE } /** * FOR UPDATE wait mode. */ enum LockWait { /** * Standard For update clause. */ WAIT, /** * For update with No Wait option. */ NOWAIT, /** * For update with Skip Locked option. */ SKIPLOCKED } /** * Return the ExpressionFactory used by this query. */ ExpressionFactory getExpressionFactory(); /** * Returns true if this query was tuned by autoTune. */ boolean isAutoTuned(); /** * Return true if this is countDistinct query. */ boolean isCountDistinct(); /** * @deprecated migrate to {@link #usingTransaction(Transaction)} then delete(). *

* Execute as a delete query returning the number of rows deleted using the given transaction. *

* Note that if the query includes joins then the generated delete statement may not be * optimal depending on the database platform. * * @return the number of beans/rows that were deleted. */ @Deprecated(forRemoval = true, since = "14.1.0") int delete(Transaction transaction); /** * @deprecated migrate to {@link #usingTransaction(Transaction)} then update(). *

* Execute the UpdateQuery returning the number of rows updated using the given transaction. * * @return the number of beans/rows updated. */ @Deprecated(forRemoval = true, since = "14.1.0") int update(Transaction transaction); /** * Execute the UpdateQuery returning the number of rows updated. * * @return the number of beans/rows updated. */ int update(); /** * Set a named bind parameter. Named parameters have a colon to prefix the name. *

{@code
   *
   * // a query with a named parameter
   * String oql = "find order where status = :orderStatus";
   *
   * List list = DB.find(Order.class, oql)
   *   .setParameter("orderStatus", OrderStatus.NEW)
   *   .findList();
   *
   * }
* * @param name the parameter name * @param value the parameter value */ 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. *
{@code
   *
   * // a query with a positioned parameter
   * String oql = "where status = ? order by id desc";
   *
   * List list = DB.createQuery(Order.class, oql)
   *   .setParameter(1, OrderStatus.NEW)
   *   .findList();
   *
   * }
* * @param position the parameter bind position starting from 1 (not 0) * @param value the parameter bind value. */ Query setParameter(int position, Object value); /** * Bind the next positioned parameter. * *
{@code
   *
   * // a query with a positioned parameters
   * String oql = "where status = ? and name = ?";
   *
   * List list = DB.createQuery(Order.class, oql)
   *   .setParameter(OrderStatus.NEW)
   *   .setParameter("Rob")
   *   .findList();
   *
   * }
*/ Query setParameter(Object value); /** * Bind all the positioned parameters. *

* A convenience for multiple calls to {@link #setParameter(Object)} */ Query setParameters(Object... values); /** * 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. * *

{@code
   *
   * Order order = DB.find(Order.class)
   *     .setId(1)
   *     .fetch("details")
   *     .findOne();
   *
   * // the order details were eagerly fetched
   * List details = order.getDetails();
   *
   * }
*/ Query setId(Object id); /** * Return the Id value. */ Object getId(); /** * Add a single Expression to the where clause returning the query. *
{@code
   *
   * List newOrders = DB.find(Order.class)
   * 		.where().eq("status", Order.NEW)
   * 		.findList();
   * ...
   *
   * }
*/ 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. *
{@code
   *
   * List orders = DB.find(Order.class)
   *     .where()
   *       .eq("status", Order.NEW)
   *       .ilike("customer.name","rob%")
   *     .findList();
   *
   * }
* * @return The ExpressionList for adding expressions to. * @see Expr */ ExpressionList where(); /** * Add Full text search expressions for Document store queries. *

* This is currently ElasticSearch only and provides the full text * expressions such as Match and Multi-Match. *

* This automatically makes this query a "Doc Store" query and will execute * against the document store (ElasticSearch). *

* Expressions added here are added to the "query" section of an ElasticSearch * query rather than the "filter" section. *

* Expressions added to the where() are added to the "filter" section of an * ElasticSearch query. */ ExpressionList text(); /** * 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. * *

{@code
   *
   * List list = DB.find(Customer.class)
   *     .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. */ 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). * * @return The ExpressionList for adding more expressions to. * @see Expr */ ExpressionList having(); /** * 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 */ Query having(Expression addExpressionToHaving); /** * @deprecated migrate to {@link #orderBy()}. */ @Deprecated(since = "13.19", forRemoval = true) default Query order(String orderByClause) { return orderBy(orderByClause); } /** * @deprecated migrate to {@link #orderBy()}. */ @Deprecated(since = "13.19", forRemoval = true) default OrderBy order() { return orderBy(); } /** * @deprecated migrate to {@link #setOrderBy(OrderBy)}. */ @Deprecated(since = "13.19", forRemoval = true) default Query setOrder(OrderBy orderBy) { return setOrderBy(orderBy); } /** * 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 the same as order() */ OrderBy orderBy(); /** * Return the first row value. */ int getFirstRow(); /** * Return the max rows for this query. */ int getMaxRows(); /** * Return true if this query has forUpdate set. */ boolean isForUpdate(); /** * Return the "for update" wait mode to use. */ LockWait getForUpdateLockWait(); /** * Return the lock type (strength) to use with "for update". */ LockType getForUpdateLockType(); /** * Returns the inherit type. This is normally the same as getBeanType() returns as long as no other type is set. */ Class getInheritType(); /** * Return the type of query being executed. */ QueryType getQueryType(); /** * 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. */ Query setProfileLocation(ProfileLocation profileLocation); /** * Type safe query bean properties and expressions (marker interface). *

* Implemented by query bean properties and expressions based on those properties. *

* The base type determines which {@link StdOperators} can be used on the property. * * @param The property type. */ interface Property { /** * Return a property given the expression. */ static Property of(String expression) { return new SimpleProperty<>(expression); } /** * Return the property in string expression form. *

* This is a path to a database column (like "name" or "billingAddress.city") or a function * wrapping a path (like lower(name), concat(name, '-', billingAddress.city) */ @Override String toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy