为特定的 JOOQ 列自动转换 RHS 值

Automatically casting RHS values for specific JOOQ columns

我有以下代码,其中 "CI_COL" 是 citext (https://www.postgresql.org/docs/current/static/citext.html)

类型
String str = "testING";

int countBad = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
  .from(Tables.MY_TABLE)
  .where(Tables.MY_TABLE.CI_COL.eq(str)));

int countGood = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
  .from(Tables.MY_TABLE)
  .where(Tables.MY_TABLE.CI_COL.eq(cast(str, new DefaultDataType<>(SQLDialect.POSTGRES, String.class, "citext")))));

第一次查询returns0,第二次查询正确returns > 0.

我花了很长时间才找到根本原因,因为当打印第一个查询(或在 DEBUG 日志记录中找到)时,它似乎在终端中执行得很好。

一旦我深入到语句级别并实际开始绑定值,这似乎就是根本原因所在。这似乎是 postgres 驱动程序中的一个问题(或故意的)。 post 说明了 citext 的绑定问题:https://www.postgresql.org/message-id/CAJFs0QB90bo0vWw5pZcw0c%3DLjOcOX04qPEM4nSd6uY7-T2r5hA%40mail.gmail.com

是否可以通过让 JOOQ 自动对特定列的所有右侧值执行转换来在 JOOQ 级别解决此问题?

旁注

new DefaultDataType<>(...)

哎呀!您正在使用内部 API :)

正确解法

在 jOOQ 中引入新数据类型的正确方法是使用 Converter,或者在本例中是数据类型 Binding:

http://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings

虽然大多数 Binding 方法的实现会简单地委托给 jOOQ 的 DefaultBinding,但您可以将 sql() 方法(生成绑定变量的 SQL 字符串)覆盖到这个:

@Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
    ctx.render().sql("?::citext");
}