raw()

Raw 表达式允许我们在查询的 where 子句中使用任何特定于数据库的函数或表达式。

// 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);

 


便利表达式

这些表达式将其他简单表达式组合在一起。我们有这些表达式,因为它们在应用程序中出现得足够频繁。

inRange()

property >= value1 and property < value2

.orderDate.inRange(today.minusDays(7), today)

InRange 表达式类似于 BETWEEN,除了它是“半开区间”。property “严格小于”上限值,而不是小于或等于上限值。

这使得 inRange 在定义时间戳和日期等内容的区间时更实用。

inRangeWith()

property <= ? and ( highProperty > ? or highProperty is null)

.startDate.inRangeWith(endDate, asAt)

这最常用于“有效日期”或“有效范围”,其中你有 2 个属性,如 startDate 和 endDate,它们形成一个范围。

inOrEmpty()

这是一个“条件 IN”,其中仅在集合不为空时才添加 IN 表达式。

List<Long> customerIds = ...

// only add the expression if the customerIds is not empty
.customer.id.inOrEmpty(customerIds)

只有在 customerIds 集合不为 null 且不为空时,以上内容才会添加 IN 表达式。

rawOrEmpty()

这是一个“条件 raw 表达式”,其中 raw 表达式使用集合(如 raw 子查询表达式),并且仅在集合不为空时才添加该表达式。

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)

 


简单表达式

以下表达式是简单表达式。

isNull()

关联的多属性上的 IsNull 转换为 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 表达式应在 ToMany 属性上使用。使用 sql exists 子查询来实现 isEmpty 表达式。

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()

当我们有 3 个或更多属性的复合自然键,并且我们有同时提供自然键的 eqin 表达式的查询(共同涵盖构成自然键的所有属性)时,使用 inPairs()

@Cache(naturalKey = {"store","code","sku"})
@Entity
public class ProductRange {
  ...
}

使用 .store.eq("myStoreCode") 表达式与 .inPairs(pairs) 表达式结合,我们定义了涵盖所有 store、code 和 sku 属性的完整自然键。

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();

当我们的 in 子句有 2 个属性时,我们使用 inPairs。相反,如果我们有 2 个属性的 eq 表达式,那么我们的 in 子句就只有通常的单个属性。

例如

new QProductRange()
    .store.eq("myStoreCode")
    .code.eq(1004)
    .in("S2", "S3", "S4")
    .setBeanCacheMode(CacheMode.ON)
    .order("sku desc")
    .findList();

对于上述查询,我们有 eqin 表达式,它们结合起来产生唯一的自然键。Ebean 可以针对此查询命中 L2 自然键缓存。

like

对于 like,我们使用 SQL %_ 占位符字符来匹配 varchar 属性。

List<Contact> contacts =
  new QContact()
    .firstName.like("Rob%")
    .findList();

ilike - 不区分大小写的 like

对于 ilike,我们使用 SQL %_ 占位符字符来匹配 varchar 属性。

List<Contact> contacts =
  new QContact()
    .firstName.ilike("Rob%")
    .findList();

startsWith

List<Contact> contacts =
  new QContact()
    .firstName.startsWith("Rob")
    .findList();

istartsWith - 不区分大小写的 startsWith

List<Contact> contacts =
  new QContact()
    .firstName.istartsWith("Rob")
    .findList();

endsWith

List<Contact> contacts =
  new QContact()
    .email.endsWith("@foo.com")
    .findList();

iendsWith - 不区分大小写的 endsWith

List<Contact> contacts =
  new QContact()
    .email.iendsWith("@foo.com")
    .findList();

contains

List<Contact> contacts =
  new QContact()
    .email.contains("ob")
    .findList();

eq - 等于

List<Order> orders =
  new QOrder()
    .status.eq(Order.Status.NEW)
    .findList();

ieq - 不区分大小写的等于

List<Customer> orders =
  new QCustomer()
    .name.ieq("rob")
    .findList();

ne - 不等于

List<Order> orders =
  new QOrder()
    .status.ne(Order.Status.NEW)
    .findList();

gt - 大于

List<Order> orders =
  new QOrder()
    .whenCreated.gt(LocalDate.now().minusDays(7))
    .findList();

ge - 大于或等于

List<Order> orders =
  new QOrder()
    .whenCreated.ge(LocalDate.now().minusDays(7))
    .findList();

lt - 小于

List<Order> orders =
  new QOrder()
    .lines.orderQuantity.lt(10)
    .findList();

le - 小于或等于

List<Order> orders =
  new QOrder()
    .lines.orderQuantity.le(10)
    .findList();

between

List<Order> orders =
  new QOrder()
    .orderDate.between(firstDay, lastDay)
    .findList();

betweenProperties

当一个值介于 2 个属性之间时。

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)

以下表达式适用于 @DbArray。在这些示例中,contact phoneNumbers 是 @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();