|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
T
- the type of Entity bean this query will fetch.public interface Query<T>
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(); ...
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.
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 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.
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
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)
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.
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.
The full WHERE clause is constructed by appending together
The above is the order that these are clauses are appended to give the full WHERE clause.
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 RawSql
.
Nested Class Summary | |
---|---|
static class |
Query.Type
The type of query result. |
Method Summary | |
---|---|
void |
cancel()
Cancel the query execution if supported by the underlying database and driver. |
Query<T> |
fetch(String path)
Specify a path to load including all its properties. |
Query<T> |
fetch(String path,
FetchConfig joinConfig)
Additionally specify a JoinConfig to specify a "query join" and or define the lazy loading query. |
Query<T> |
fetch(String path,
String fetchProperties)
Specify a path to fetch with its specific properties to include (aka partial object). |
Query<T> |
fetch(String assocProperty,
String fetchProperties,
FetchConfig fetchConfig)
Additionally specify a FetchConfig to use a separate query or lazy loading to load this path. |
ExpressionList<T> |
filterMany(String propertyName)
This applies a filter on the 'many' property list rather than the root level objects. |
FutureIds<T> |
findFutureIds()
Execute find Id's query in a background thread. |
FutureList<T> |
findFutureList()
Execute find list query in a background thread. |
FutureRowCount<T> |
findFutureRowCount()
Execute find row count query in a background thread. |
List<Object> |
findIds()
Execute the query returning the list of Id's. |
List<T> |
findList()
Execute the query returning the list of objects. |
Map<?,T> |
findMap()
Execute the query returning a map of the objects. |
PagingList<T> |
findPagingList(int pageSize)
Return a PagingList for this query. |
int |
findRowCount()
Return the count of entities this query should return. |
Set<T> |
findSet()
Execute the query returning the set of objects. |
T |
findUnique()
Execute the query returning either a single bean or null (if no matching bean is found). |
ExpressionFactory |
getExpressionFactory()
Return the ExpressionFactory used by this query. |
int |
getFirstRow()
Return the first row value. |
String |
getGeneratedSql()
Return the sql that was generated for executing this query. |
int |
getMaxRows()
Return the max rows for this query. |
RawSql |
getRawSql()
Return the RawSql that was set to use for this query. |
Query.Type |
getType()
Return the type of query (List, Set, Map, Bean, rowCount etc). |
ExpressionList<T> |
having()
Add Expressions to the Having clause return the ExpressionList. |
Query<T> |
having(Expression addExpressionToHaving)
Add an expression to the having clause returning the query. |
Query<T> |
having(String addToHavingClause)
Add additional clause(s) to the having clause. |
boolean |
isAutofetchTuned()
Returns true if this query was tuned by autoFetch. |
Query<T> |
join(String path)
Same as fetch(String) |
Query<T> |
join(String path,
JoinConfig joinConfig)
Same as fetch(String, FetchConfig) |
Query<T> |
join(String assocProperty,
String fetchProperties)
Same as fetch(String, String) . |
Query<T> |
join(String assocProperty,
String fetchProperties,
JoinConfig joinConfig)
Additionally specify a JoinConfig to specify a "query join" and or define the lazy loading query. |
OrderBy<T> |
order()
Return the OrderBy so that you can append an ascending or descending property to the order by clause. |
Query<T> |
order(String orderByClause)
Set the order by clause replacing the existing order by clause if there is one. |
OrderBy<T> |
orderBy()
Return the OrderBy so that you can append an ascending or descending property to the order by clause. |
Query<T> |
orderBy(String orderByClause)
Set the order by clause replacing the existing order by clause if there is one. |
Query<T> |
select(String fetchProperties)
Explicitly set a comma delimited list of the properties to fetch on the 'main' entity bean (aka partial object). |
Query<T> |
setAutofetch(boolean autofetch)
Explicitly specify whether to use Autofetch for this query. |
Query<T> |
setBackgroundFetchAfter(int backgroundFetchAfter)
Set the rows after which fetching should continue in a background thread. |
Query<T> |
setBufferFetchSizeHint(int fetchSize)
A hint which for JDBC translates to the Statement.fetchSize(). |
Query<T> |
setDistinct(boolean isDistinct)
Set whether this query uses DISTINCT. |
Query<T> |
setFirstRow(int firstRow)
Set the first row to return for this query. |
Query<T> |
setId(Object id)
Set the Id value to query. |
Query<T> |
setListener(QueryListener<T> queryListener)
Set a listener to process the query on a row by row basis. |
Query<T> |
setLoadBeanCache(boolean loadBeanCache)
When set to true all the beans from this query are loaded into the bean cache. |
Query<T> |
setMapKey(String mapKey)
Set the property to use as keys for a map. |
Query<T> |
setMaxRows(int maxRows)
Set the maximum number of rows to return in the query. |
Query<T> |
setOrder(OrderBy<T> orderBy)
Set an OrderBy object to replace any existing OrderBy clause. |
Query<T> |
setOrderBy(OrderBy<T> orderBy)
Set an OrderBy object to replace any existing OrderBy clause. |
Query<T> |
setParameter(int position,
Object value)
Set an ordered bind parameter according to its position. |
Query<T> |
setParameter(String name,
Object value)
Set a named bind parameter. |
Query<T> |
setQuery(String oql)
Deprecated. |
Query<T> |
setRawSql(RawSql rawSql)
Set RawSql to use for this query. |
Query<T> |
setReadOnly(boolean readOnly)
When set to true when you want the returned beans to be read only. |
Query<T> |
setTimeout(int secs)
Set a timeout on this query. |
Query<T> |
setUseCache(boolean useBeanCache)
Set this to true to use the bean cache. |
Query<T> |
setUseQueryCache(boolean useQueryCache)
Set this to true to use the query cache. |
Query<T> |
setVanillaMode(boolean vanillaMode)
Set this to true and the beans and collections returned will be plain classes rather than Ebean generated dynamic subclasses etc. |
ExpressionList<T> |
where()
Add Expressions to the where clause with the ability to chain on the ExpressionList. |
Query<T> |
where(Expression expression)
Add a single Expression to the where clause returning the query. |
Query<T> |
where(String addToWhereClause)
Add additional clause(s) to the where clause. |
Method Detail |
---|
Query.Type getType()
RawSql getRawSql()
Query<T> setRawSql(RawSql rawSql)
void cancel()
This must be called from a different thread to the query executor.
ExpressionFactory getExpressionFactory()
boolean isAutofetchTuned()
Query<T> setAutofetch(boolean autofetch)
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.
Query<T> setQuery(String oql)
EbeanServer.createQuery(Class, String)
.
Set the query using the query language.
Query<T> select(String fetchProperties)
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();
fetchProperties
- the properties to fetch for this bean (* = all properties).Query<T> fetch(String path, String fetchProperties)
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();
path
- the path of an associated (1-1,1-M,M-1,M-M) bean.fetchProperties
- properties of the associated bean that you want to include in
the fetch (* means all properties, null also means all
properties).Query<T> join(String assocProperty, String fetchProperties)
fetch(String, String)
.
This will eventually be deprecated in favour of the matching "fetch" method.
Query<T> fetch(String assocProperty, String fetchProperties, FetchConfig fetchConfig)
Query<T> join(String assocProperty, String fetchProperties, JoinConfig joinConfig)
This will eventually be deprecated in favour of the matching "fetch" method.
Query<T> fetch(String path)
The same as fetch(String, String)
with the fetchProperties as "*".
path
- the property of an associated (1-1,1-M,M-1,M-M) bean.Query<T> join(String path)
fetch(String)
This will eventually be deprecated in favour of the matching "fetch" method.
Query<T> fetch(String path, FetchConfig joinConfig)
Query<T> join(String path, JoinConfig joinConfig)
fetch(String, FetchConfig)
This will eventually be deprecated in favour of the matching "fetch" method.
List<Object> findIds()
This query will execute against the EbeanServer that was used to create it.
EbeanServer.findIds(Query, Transaction)
List<T> findList()
This query will execute against the EbeanServer that was used to create it.
EbeanServer.findList(Query, Transaction)
Set<T> findSet()
This query will execute against the EbeanServer that was used to create it.
EbeanServer.findSet(Query, Transaction)
Map<?,T> findMap()
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();
EbeanServer.findMap(Query, Transaction)
T findUnique()
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(); ...
int findRowCount()
This is the number of 'top level' or 'root level' entities.
FutureRowCount<T> findFutureRowCount()
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).
FutureIds<T> findFutureIds()
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).
FutureList<T> findFutureList()
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).
PagingList<T> findPagingList(int pageSize)
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
setFirstRow(int)
and and 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.
pageSize
- the number of beans fetched per PageQuery<T> setParameter(String name, Object value)
// 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();
name
- the parameter namevalue
- the parameter valueQuery<T> setParameter(int position, Object value)
// 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();
position
- the parameter bind position starting from 1 (not 0)value
- the parameter bind value.Query<T> setListener(QueryListener<T> queryListener)
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();
Query<T> setId(Object id)
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(); ...
Query<T> where(String addToWhereClause)
This typically contains named parameters which will need to be set via
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.
addToWhereClause
- the clause to append to the where clause which typically
contains named parameters.
Query<T> where(Expression expression)
List<Order> newOrders = Ebean.find(Order.class) .where().eq("status", Order.NEW) .findList(); ...
ExpressionList<T> where()
Query<Order> query = Ebean.createQuery(Order.class, "top"); ... if (...) { query.where() .eq("status", Order.NEW) .ilike("customer.name","rob%"); }
Expr
ExpressionList<T> filterMany(String propertyName)
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.
propertyName
- the name of the many property that you
want to have a filter on.
ExpressionList<T> having()
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).
Expr
Query<T> having(String addToHavingClause)
This typically contains named parameters which will need to be set via
setParameter(String, Object)
.
Query<ReportOrder> query = Ebean.createQuery(ReportOrder.class); ... if (...) { query.having("score > :min"); query.setParameter("min", 1); }
addToHavingClause
- the clause to append to the having clause which typically
contains named parameters.
Query<T> having(Expression addExpressionToHaving)
Currently only beans based on raw sql will use the having clause.
This is similar to having()
except it returns the query rather
than the ExpressionList. This is useful when you want to further specify
something on the query.
addExpressionToHaving
- the expression to add to the having clause.
Query<T> orderBy(String orderByClause)
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 order(String)
.
Query<T> order(String orderByClause)
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 orderBy(String)
.
OrderBy<T> order()
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 orderBy()
.
OrderBy<T> orderBy()
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 order()
.
Query<T> setOrder(OrderBy<T> orderBy)
This is EXACTLY the same as setOrderBy(OrderBy)
.
Query<T> setOrderBy(OrderBy<T> orderBy)
This is EXACTLY the same as setOrder(OrderBy)
.
Query<T> setDistinct(boolean isDistinct)
Query<T> setVanillaMode(boolean vanillaMode)
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 ServerConfig.setVanillaMode(boolean)
.
ServerConfig.setVanillaMode(boolean)
,
ServerConfig.setVanillaRefMode(boolean)
int getFirstRow()
Query<T> setFirstRow(int firstRow)
firstRow
- int getMaxRows()
Query<T> setMaxRows(int maxRows)
maxRows
- the maximum number of rows to return in the query.Query<T> setBackgroundFetchAfter(int backgroundFetchAfter)
backgroundFetchAfter
- Query<T> setMapKey(String mapKey)
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(); ...
mapKey
- the property to use as keys for a map.Query<T> setUseCache(boolean useBeanCache)
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.
Query<T> setUseQueryCache(boolean useQueryCache)
Query<T> setReadOnly(boolean readOnly)
Query<T> setLoadBeanCache(boolean loadBeanCache)
Query<T> setTimeout(int secs)
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.
secs
- the query timeout limit in seconds. Zero means there is no
limit.Query<T> setBufferFetchSizeHint(int 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.
String getGeneratedSql()
This is only available after the query has been executed and provided only for informational purposes.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |