加入 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
。
其他确实需要加入的情况,
我有三个 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
。
其他确实需要加入的情况,