如何使用jOOQ的Multiset获取关联完整记录列表?
解决jOOQ中获取主记录关联完整子记录列表的问题
原代码核心问题
- 关联条件错误:
ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID.eq(ENGAGEMENT_NOTE.ID)应关联到参会者表主键ENGAGEMENT_NOTE_ATTENDEE.ID,而非主表ID - Multiset查询未明确指定子表完整字段,可能导致记录缺失
- 结果映射时类型转换方式不合理,未利用jOOQ的类型安全特性
修正后的代码
context.select( ENGAGEMENT_NOTE.asterisk(), multiset( select(ENGAGEMENT_NOTE_ATTENDEE.asterisk()) .from(ENGAGEMENT_NOTE_ATTENDANCE) .join(ENGAGEMENT_NOTE_ATTENDEE) .on(ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID.eq(ENGAGEMENT_NOTE_ATTENDEE.ID)) .where(ENGAGEMENT_NOTE_ATTENDANCE.ENGAGEMENT_NOTE_ID.eq(ENGAGEMENT_NOTE.ID)) ).convertFrom { it.into(ENGAGEMENT_NOTE_ATTENDEE) } .`as`("attendees") ) .from(ENGAGEMENT_NOTE) .where(ENGAGEMENT_NOTE.ID.eq(noteId.value)) .fetchOne() ?.let { record -> EngagementNoteView( record.into(ENGAGEMENT_NOTE), record.getValue(record.field("attendees", List::class.java)) as List<EngagementNoteAttendeeRecord> ) }
关键修正说明
- 修正关联逻辑:将join条件调整为关联参会者表主键,确保主表与子表关联关系正确
- 明确子表字段:在multiset查询中指定
ENGAGEMENT_NOTE_ATTENDEE.asterisk(),保证获取参会者的完整记录 - 安全获取子列表:通过
record.field("attendees", List::class.java)明确字段类型,降低类型转换风险;若使用jOOQ 3.17+,可预先定义类型安全字段引用:
之后直接用val ATTENDEES = multiset(...).convertFrom(...).`as`("attendees", SQLDataType.OTHER.asConvertedDataType(List::class.java))record.getValue(ATTENDEES)获取类型安全的列表 - 优化映射逻辑:用
let替代map处理单条记录,语义更贴合场景
内容的提问来源于stack exchange,提问作者Niamh
相关产品推荐
相关产品推荐

