在JOOQ中映射相同类型的连接表

Man*_*rdt 5 java sql scala jooq

我有以下查询:

sql
  .select()
  .from(ITEMS.join(ITEMSOWNERS).on(ITEMSOWNERS.ITEM_ID.eq(ITEMS.ID)))
             .join(USERS).on(ITEMSOWNERS.OWNER_ID.eq(USERS.ID))
             .leftJoin(ITEMSREVIEWERS).on(ITEMSREVIEWERS.ITEM_ID.eq(ITEMS.ID))
             .join(USERS).on(ITEMSREVIEWERS.REVIEWER_ID.eq(USERS.ID))
  .where(PUBLIC_ID.eq(publicId))
  .fetchGroups(WALLETS)
Run Code Online (Sandbox Code Playgroud)

我想以某种元组形式返回这些结果,考虑到USERS这里有两种类型的结果,即我有这样的结构:

- ITEMS (given the `WHERE` clause there should be only one of those at most, though)
  - OWNERS
  - REVIEWERS
Run Code Online (Sandbox Code Playgroud)

我想我知道我可以使用fetchGroupsfromRecord到 a Map<Item, Record>,但我不太确定如何进一步处理应包含Record两次的结果User,即

innerRecord.into(USERS) // this should work okay, I guess
innerRecord.into(USERS) // how to make this happen on the "second" set of User columns?
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想将第二个映射User到一个,Optional因为它可能不存在。

Luk*_*der 5

您需要为USERS表添加别名。如果您两次连接同一个表,这在 SQL 中通常是一个好主意(无论您是否使用 jOOQ):

val owners = USERS.as("owners");
val reviewers = USERS.as("reviewers");

sql
  .select()
  .from(ITEMS.join(ITEMSOWNERS).on(ITEMSOWNERS.ITEM_ID.eq(ITEMS.ID)))
             .join(owners).on(ITEMSOWNERS.OWNER_ID.eq(owners.ID))
             .leftJoin(ITEMSREVIEWERS).on(ITEMSREVIEWERS.ITEM_ID.eq(ITEMS.ID))
             .join(reviewers).on(ITEMSREVIEWERS.REVIEWER_ID.eq(reviewers.ID))
  .where(PUBLIC_ID.eq(publicId))
  .fetchGroups(WALLETS)
Run Code Online (Sandbox Code Playgroud)

然后,您可以显式访问两个表的列,如下所示:

innerRecord.into(owners)
innerRecord.into(reviewers)
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想将第二个用户映射到可选,因为它可能不存在。

jOOQ中没有这样的方法。将其显式包装如下:

Optional.of(innerRecord.into(reviewers))
Run Code Online (Sandbox Code Playgroud)

关于 SQL 正确性的说明

我认为你的 SQL 查询不正确。您应该将审阅者表左连接到连接图:

  .from(ITEMS.join(ITEMSOWNERS).on(ITEMSOWNERS.ITEM_ID.eq(ITEMS.ID)))
             .join(owners).on(ITEMSOWNERS.OWNER_ID.eq(owners.ID))
             .leftJoin(ITEMSREVIEWERS).on(ITEMSREVIEWERS.ITEM_ID.eq(ITEMS.ID))
             .leftJoin(reviewers).on(ITEMSREVIEWERS.REVIEWER_ID.eq(reviewers.ID))
Run Code Online (Sandbox Code Playgroud)

...或按如下方式连接的嵌套:

  .from(ITEMS.join(ITEMSOWNERS).on(ITEMSOWNERS.ITEM_ID.eq(ITEMS.ID)))
             .join(owners).on(ITEMSOWNERS.OWNER_ID.eq(owners.ID))
             .leftJoin(ITEMSREVIEWERS
                 .join(reviewers).on(ITEMSREVIEWERS.REVIEWER_ID.eq(reviewers.ID))
             ).on(ITEMSREVIEWERS.ITEM_ID.eq(ITEMS.ID))
Run Code Online (Sandbox Code Playgroud)