raw()
The Raw expression lets us use any database specific function or expression in the where clause of a query.
// e.g. use a database function
.raw("add_days(orderDate, 10) < ?", someDate)
// e.g. subquery
.raw("customer.id in (select o.customer_id from orders o where o.id in (?1))", orderIds);
Convenience expressions
These are expressions that combine other simple expressions together. We have them because they occur often enough in applications.
inRange()
property >= value1 and property < value2
.orderDate.inRange(today.minusDays(7), today)
InRange expression is similar to BETWEEN except is "half open interval".
The property is strictly less than
the top value rather than
being less than or equal to.
This makes inRange more practically useful to define intervals on things like timestamps and dates etc.
inRangeWith()
property <= ? and ( highProperty > ? or highProperty is null)
.startDate.inRangeWith(endDate, asAt)
This is most commonly used for "effective dating" or an "effective range" where you have 2 properties like startDate and endDate that form a range.
inOrEmpty()
This is a "conditional IN" where the IN expression is only added if the collection is not empty.
List<Long> customerIds = ...
// only add the expression if the customerIds is not empty
.customer.id.inOrEmpty(customerIds)
The above will only add the IN expression if the customerIds collection is not null and not empty.
rawOrEmpty()
This is a "conditional raw expression" where the raw expression uses a collection (like a raw subquery expression) and we only add the expression if the collection is not empty.
List<String> names = ...
// only add the expression if the names is not empty
.rawOrEmpty("customer.id in (select c.id from customer c where c.name in (?1))", names)
Simple expressions
The following expressions are simple expressions.
isNull()
IsNull on a associated many property translates to isEmpty()
new QOrder()
.lines.isNull()
.findList();
select ...
from orders t0
where not exists (select 1 from order_lines x where x.order_id = t0.id)
isEmpty()
IsEmpty expression should be used on a ToMany property. A sql exists subquery is used to implement the isEmpty expression.
new QOrder()
.lines.isEmpty()
.findList();
select ...
from orders t0
where not exists (select 1 from order_lines x where x.order_id = t0.id)
in()
new QOrder()
.status.in(Order.Status.NEW, Order.Status.PENDING)
.findList();
inPairs()
inPairs()
is used when we have a compound natual key with 3 or more properties
and we have queries that combine eq
and in
expressions
that together provide the natural key (together cover all the properties that make up the
natural key).
@Cache(naturalKey = {"store","code","sku"})
@Entity
public class ProductRange {
...
}
With the .store.eq("myStoreCode")
expression combined with the
.inPairs(pairs)
expression we have defined complete natural
keys covering all of the store, code and sku
properties.
Pairs pairs = new Pairs("sku", "code")
.add("S2", 1000)
.add("S2", 1001)
.add("S3", 1000);
new QProductRange()
.store.eq("myStoreCode")
.inPairs(pairs)
.setBeanCacheMode(CacheMode.ON)
.order("sku desc")
.findList();
We are using inPairs when our in clause has 2 properties. If instead we have
the eq
expression with 2 properties then our in clause just has
the usual single property.
For example:
new QProductRange()
.store.eq("myStoreCode")
.code.eq(1004)
.in("S2", "S3", "S4")
.setBeanCacheMode(CacheMode.ON)
.order("sku desc")
.findList();
With the above query we have eq
and in
expressions that
combine to produce unique natural keys. Ebean can hit L2 natural key cache for this query.
like
With like
we use the SQL %
and _
place holder
characters to match varchar properties.
List<Contact> contacts =
new QContact()
.firstName.like("Rob%")
.findList();
ilike - case-insensitive like
With ilike
we use the SQL %
and _
place holder
characters to match varchar properties.
List<Contact> contacts =
new QContact()
.firstName.ilike("Rob%")
.findList();
startsWith
List<Contact> contacts =
new QContact()
.firstName.startsWith("Rob")
.findList();
istartsWith - case-insensitive startsWith
List<Contact> contacts =
new QContact()
.firstName.istartsWith("Rob")
.findList();
endsWith
List<Contact> contacts =
new QContact()
.email.endsWith("@foo.com")
.findList();
iendsWith - case-insensitive endsWith
List<Contact> contacts =
new QContact()
.email.iendsWith("@foo.com")
.findList();
contains
List<Contact> contacts =
new QContact()
.email.contains("ob")
.findList();
eq - equal to
List<Order> orders =
new QOrder()
.status.eq(Order.Status.NEW)
.findList();
ieq - case-insensitive equal to
List<Customer> orders =
new QCustomer()
.name.ieq("rob")
.findList();
ne - not equal
List<Order> orders =
new QOrder()
.status.ne(Order.Status.NEW)
.findList();
gt - greater than
List<Order> orders =
new QOrder()
.whenCreated.gt(LocalDate.now().minusDays(7))
.findList();
ge - greater than or equal
List<Order> orders =
new QOrder()
.whenCreated.ge(LocalDate.now().minusDays(7))
.findList();
lt - less than
List<Order> orders =
new QOrder()
.lines.orderQuantity.lt(10)
.findList();
le - less than or equal
List<Order> orders =
new QOrder()
.lines.orderQuantity.le(10)
.findList();
between
List<Order> orders =
new QOrder()
.orderDate.between(firstDay, lastDay)
.findList();
betweenProperties
When a value is between 2 properties.
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
...
.where().betweenProperties("effectiveStart", "effectiveEnd", timestamp)
bitwiseAny
flags.bitwiseAny(BwFlags.HAS_BULK + BwFlags.HAS_SIZE)
bitwiseAnd
int selectedFlags = BwFlags.HAS_BULK + BwFlags.HAS_SIZE;
int mask = BwFlags.HAS_SIZE; // Only Size flag set
bitwiseAnd(selectedFlags, mask)
bitwiseAll
flags.bitwiseAll(BwFlags.HAS_BULK + BwFlags.HAS_COLOUR)
bitwiseNot
flags.bitwiseNot(BwFlags.HAS_COLOUR)
The following expressions are for @DbArray
.
In these examples contact phoneNumbers is a @DbArray
.
arrayContains
new QContact()
.phoneNumbers.contains("4321")
.findList();
arrayNotContains
new QContact()
.phoneNumbers.notContains("4321")
.findList();
arrayIsEmpty
new QContact()
.phoneNumbers.isEmpty()
.findList();
arrayIsNotEmpty
new QContact()
.phoneNumbers.isNotEmpty()
.findList();