首页 > 解决方案 > 如何通过 JOOQ 中的复合主键选择多行?

问题描述

我有一个带有复合主键的表。我想用一组主键查找行。

我的桌子是:

create table test_tbl
(
    id_part_1 varchar(36) not null,
    id_part_2 varchar(36) not null,
    some_data text not null,
    constraint test_tbl_pkey
        primary key (id_part_1, id_part_2)
);

我的SQL查询是:

SELECT * FROM test_tbl
    WHERE (id_part_1, id_part_2) IN (('id_part_1_1', 'id_part_2_1'), ('id_part_1_2', 'id_part_2_2'));

那么,如何在 JOOQ 的帮助下实现这个查询呢?我不生成 JOOQ Dao,我只有 JOOQ 表。

标签: javapostgresqlselectjooqcomposite-primary-key

解决方案


如何手动执行此操作

您可以使用DSL.row()构造行值表达式将 SQL 查询直接转换为 jOOQ,然后:

row(TEST_TBL.ID_PART_1, TEST_TBL.ID_PART_2).in(
  row("id_part_1_1", "id_part_2_1"),
  row("id_part_1_2", "id_part_2_2")
);

另请参阅关于谓词 degree > 1的jOOQ 手册部分IN

使用可嵌入键

或者,您可以从新的 jOOQ 3.14<embeddablePrimaryKeys/>功能提供的额外类型安全中获益,该功能允许您为所有主键及其引用外键生成记录类型。然后您的查询将显示为:

ctx.select()
   .from(TEST_TBL)
   .where(TEST_TBL.TEST_TBL_PKEY.in(
      new TestTblPkeyRecord("id_part_1_1", "id_part_2_1"),
      new TestTblPkeyRecord("id_part_1_2", "id_part_2_2")
   ))
   .fetch();

这将产生与原始查询相同的查询,但输入安全,您将永远不会再次忘记键列。不仅在查询主键的时候,在加入的时候也一样!更改密钥将导致编译错误:

ctx.select()
   .from(TEST_TBL)
   .join(OTHER_TEST_TBL)
   .on(TEST_TBL.TEST_TBL_PKEY.eq(OTHER_TEST_TBL.TEST_TBL_PKEY.TEST_TBL_FKEY))
   .fetch();

或者一个隐式连接看起来像这样:

ctx.select(OTHER_TEST_TBL.testTbl().fields(), OTHER_TEST_TBL.fields())
   .from(OTHER_TEST_TBL)
   .fetch();

推荐阅读