【问题标题】:Querying a composite key with multiple IN values with jOOQ使用 jOOQ 查询具有多个 IN 值的复合键
【发布时间】:2020-10-23 09:17:08
【问题描述】:

我有以下疑问:

SELECT *
FROM table
WHERE (id, other_id, status)
IN (
    (1, 'XYZ', 'OK'),
    (2, 'ZXY', 'OK') -- , ...
);

是否可以使用jOOQ 以类型安全的方式构造此查询,最好不生成复合键?是否可以使用jOOQ 3.11 做到这一点?

【问题讨论】:

标签: jooq predicate composite-key


【解决方案1】:

抱歉,我的 Google-fu 似乎没有达到标准。这个问题的反面可以在这里找到:Use JOOQ to do a delete specifying multiple columns in a "not in" clause

为了完整起见,以便其他 Google 搜索可能更直接有用,解决方案是:

// can be populated using DSL.row(...); for each entry
Collection<? extends Row3<Long, String, String>> values = ... 

dslContext.selectFrom(TABLE)
 .where(DSL.row(ID, OTHER_ID, STATUS).in(values))
 .fetch();

相关jOOQ文档:https://www.jooq.org/doc/3.14/manual/sql-building/conditional-expressions/in-predicate-degree-n/

【讨论】:

    【解决方案2】:

    Your own answer 已经展示了如何使用IN predicate for degrees > 1 从 SQL 到 jOOQ 进行 1:1 转换。

    从 jOOQ 3.14 开始,还可以选择在代码生成器中使用新的 &lt;embeddablePrimaryKeys/&gt; 标志,这将为所有主键(以及引用它们的外键)生成可嵌入类型。这将有助于永远不会忘记这些查询中的关键列,这对于连接特别有用。

    您的查询将如下所示:

    ctx.selectFrom(TABLE)
       .where(TABLE.PK_NAME.in(
          new PkNameRecord(1, "XYZ", "OK"), 
          new PkNameRecord(2, "ZXY", "OK")))
       .fetch();
    

    幕后生成的查询与您的相同,使用 3 个约束列作为谓词。如果您从键中添加或删除约束,则查询将不再编译。连接如下所示:

    ctx.select()
       .from(TABLE)
       .join(OTHER_TABLE)
       .on(TABLE.PK_NAME.eq(OTHER_TABLE.FK_NAME))
       .fetch();
    

    或者implicit join 看起来像这样:

    ctx.select(OTHER_TABLE.table().fields(), OTHER_TABLE.fields())
       .from(OTHER_TABLE)
       .fetch();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      相关资源
      最近更新 更多