一个条件就是一个字段

86 阅读2分钟

从jOOQ 3.17开始, [Condition](https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Condition.html)类型扩展了 [Field<Boolean>](https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Field.html)类型。因为,这就是SQL标准所认为的,在种类上:

<boolean value expression> ::=
  <predicate>

确切的定义包含中间规则,但你会明白这个意思。一个<predicate> (在jOOQ中是一个 [Condition](https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Condition.html)在jOOQ中是一个<boolean value expression> ,可以在任何可以使用 的地方使用,这也可以在投影、谓词和其他地方使用。

不是所有的SQL方言都是这样工作的,事实上,在SQL:1999BOOLEAN 数据类型进行标准化之前,SQL本身并不是这样工作的。例如,SQL-92<predicate> 列为可能的替代品,只用于<search condition> ,例如用于<where clause> ,但不用于任何普通的<value expression>

因此,虽然这在PostgreSQL中是有效的,它支持标准的SQLBOOLEAN 类型:

SELECT id, id > 2 AS big_id
FROM book
ORDER BY id

编制:

|id |big_id|
|---|------|
|1  |false |
|2  |false |
|3  |true  |
|4  |true  |

它在Oracle中不起作用,例如,它用通常有用的错误信息来取悦我们。

SQL错误[923] [42000]。ORA-00923:在预期的地方没有找到FROM关键字

这在jOOQ 3.16或更低版本中是如何工作的

jOOQ一直支持交换使用ConditionField<Boolean> 的方法。这里有两个封装方法。

  • DSL.field(Condition) 返回Field<Boolean>
  • DSL.condition(Field<Boolean>) 返回Condition

这在这里有记载。因此,前面的查询可以写成下面的样子:

Result<Record2<Integer, Boolean>> result =
ctx.select(BOOK.ID, field(BOOK.ID.gt(2)).as("big_id"))
//                  ^^^^^^^^^^^^^^^^^^^^ wrapping condition with field()
   .from(BOOK)
   .orderBy(BOOK.ID)
   .fetch();

生成的SQL看起来是这样的,对于PostgreSQL:

SELECT
  book.id,
  (book.id > 2) AS big_id
FROM book
ORDER BY book.id

而对于Oracle来说,这是对该功能的模拟。

SELECT
  book.id,
  CASE
    WHEN book.id > 2 THEN 1
    WHEN NOT (book.id > 2) THEN 0
  END big_id
FROM book
ORDER BY book.id

NULL 这个模拟保留了我们所喜爱的三值逻辑,即在BOOLEAN 的情况下,BOOK.IDNULL

这在jOOQ 3.17中是如何工作的,现在

从jOOQ 3.17和#11969开始,不再需要对field(Condition) 进行手动包装,你可以直接投射Condition

Result<Record2<Integer, Boolean>> result =
ctx.select(BOOK.ID, BOOK.ID.gt(2).as("big_id"))
   //               ^^^^^^^^^^^^^ no more wrapping necessary
   .from(BOOK)
   .orderBy(BOOK.ID)
   .fetch();

其行为与你包装了条件(包括结果类型)的情况完全相同,而且对于Oracle和其他不支持BOOLEAN 值表达式的方言来说,模拟仍然起作用。这意味着你也可以在其他接受Field 类型的子句中使用Condition ,包括,例如:

  • GROUP BYPARTITION BY
  • ORDER BY