加入 jOOQ 时无法获取我的 SpeakerRecord 实体
Posted
技术标签:
【中文标题】加入 jOOQ 时无法获取我的 SpeakerRecord 实体【英文标题】:Can't get my SpeakerRecord entity when joining with jOOQ 【发布时间】:2021-08-29 13:02:25 【问题描述】:我有三个表:event、speaker、event_speaker
事件和发言者具有由“event_speaker”表管理的 n:m 关系。我使用 jOOQ maven codegen 来生成像“EventRecord”和“SpeakerRecord”这样的文件。
在我的应用程序中,我想获取特定活动的所有发言人。所以我需要将“speaker”表与“event_speaker”表连接起来,才能通过事件ID来限制结果:
return dsl.select(SPEAKER.asterisk())
.from(SPEAKER)
.leftJoin(EVENT_SPEAKER).on(SPEAKER.ID.eq(EVENT_SPEAKER.SPEAKER_ID))
.where(EVENT_SPEAKER.EVENT_ID.eq(eventId))
.fetch();
现在我将得到一个Result<Record>
作为返回值。但我想得到一个Result<SpeakerRecord>
作为返回值。如果我删除加入,我会得到它(但当然结果集将包含所有发言者,这是我不想要的)。
当我需要加入时,如何获得SpeakerRecord
来代替更通用的Record
对象?
【问题讨论】:
【参考方案1】:您可以使用fetchInto
告诉 jOOQ 您期望什么结果:
return dsl.select(SPEAKER.fields())
.from(SPEAKER)
.leftJoin(EVENT_SPEAKER).on(SPEAKER.ID.eq(EVENT_SPEAKER.SPEAKER_ID))
.where(EVENT_SPEAKER.EVENT_ID.eq(eventId))
.fetchInto(SpeakerRecord.class);
【讨论】:
【参考方案2】:Your LEFT JOIN
is effectively an INNER JOIN
因为您的WHERE
子句过滤了外部连接表but what you really wanted was a semi join。在极少数情况下,您在 EVENT_SPEAKER (SPEAKER_ID, EVENT_ID)
上没有唯一键,例如因为键中有第三列,所以您会得到与当前查询重复的列。
所以,改为这样做:
return dsl
.selectFrom(SPEAKER)
.where(SPEAKER.ID.in(
select(EVENT_SPEAKER.SPEAKER_ID)
.from(EVENT_SPEAKER)
.where(EVENT_SPEAKER.EVENT_ID.eq(eventId))
))
.fetch();
假设,一如既往
import static org.jooq.impl.DSL.*;
通过上述查询,您可以再次使用DSLContext.selectFrom(Table)
,这会产生您想要的SpeakerRecord
。
在其他确实需要加入的情况下,use Simon's approach
【讨论】:
这正是我所需要的!上一次我自己使用 SQL 大约是 15 年前。我肯定需要完成一个加入教程来更新我的睡眠知识…… 顺便说一句,这是 Komunumo 的,Java User Group Switzerland 的新管理 UI... @MarcusFihlon:是的,考虑选择哪种连接类型可能会令人困惑。以下是 jOOQ 博客中的一些帖子,我认为您可能会喜欢:blog.jooq.org/2017/01/12/…,当然还有 jOOQ 手册中的:jooq.org/doc/latest/manual/sql-building/table-expressions/… @MarcusFihlon:很高兴听到您在该平台上使用 jOOQ! :) 如果您需要任何帮助,我会在这里寻求帮助!以上是关于加入 jOOQ 时无法获取我的 SpeakerRecord 实体的主要内容,如果未能解决你的问题,请参考以下文章