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

时间:2018-07-26 14:02:01

标签: 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)

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

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

我想我知道我可以使用fetchGroupsRecordMap<Item, Record>,但是我不确定如何对生成的{{1 }}应当包含两次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? 映射到User中,因为它可能不在附近。

1 个答案:

答案 0 :(得分:3)

您需要为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)

然后您可以像这样显式访问两个表的列:

innerRecord.into(owners)
innerRecord.into(reviewers)
  

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

jOOQ中没有这种方法。显式包装如下:

Optional.of(innerRecord.into(reviewers))

关于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))

...或嵌套连接如下:

  .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))