加入 jOOQ 时无法获取我的 SpeakerRecord 实体

Can't get my SpeakerRecord entity when joining with jOOQ

我有三个 table:事件、演讲者、event_speaker

事件和演讲者具有由“event_speaker”table 管理的 n:m 关系。我使用 jOOQ maven codegen 生成了像“EventRecord”和“SpeakerRecord”这样的文件。

在我的应用程序中,我想获取特定事件的所有发言人。所以我需要加入“演讲者”table 和“event_speaker”table 才能通过事件 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> 作为 return 值。但我想得到一个 Result<SpeakerRecord> 作为 return 值。如果我删除连接,我会得到它(但当然结果集将包含所有说话人,这是我不想要的)。

当我需要连接时,如何获得 SpeakerRecord 来代替更通用的 Record 对象?

您可以使用 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);

Your LEFT JOIN is effectively an INNER JOIN because your WHERE clause filters on the outer joined table, 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

其他确实需要加入的情况,