英文:
How to use multiset to get associated list of records with JOOQ?
问题
我正在尝试获取一条记录(参与记录),以及与之关联的记录列表(参与者)。我想将它们都存储为记录,但似乎无法使其工作。我在网上看到的所有多集示例都只使用了一些字段,而不是整个记录。这也是在 Kotlin 中,如果有区别的话。
下面是我正在尝试做的事情,但它不起作用。
context.select(
ENGAGEMENT_NOTE.asterisk(),
multiset(
select()
.from(ENGAGEMENT_NOTE_ATTENDANCE)
.join(ENGAGEMENT_NOTE_ATTENDEE).on(ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID.eq(ENGAGEMENT_NOTE.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()
?.map {
EngagementNoteView(
it.into(ENGAGEMENT_NOTE),
it.getValue("attendees") as List<EngagementNoteAttendeeRecord> // 这肯定是错误的。
)
}
英文:
I am trying to get a record (engagement note), along with a list of associated records (attendees). I want to store them all as records, but cannot seem to get it to work. All examples I've seen online of multiset just use a few fields rather than the entire record. This is also in Kotlin if that makes a difference.
See below for what I'm attempting to do, it does not work.
context.select(
ENGAGEMENT_NOTE.asterisk(),
multiset(
select()
.from(ENGAGEMENT_NOTE_ATTENDANCE)
.join(ENGAGEMENT_NOTE_ATTENDEE).on(ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID.eq(ENGAGEMENT_NOTE.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()
?.map {
EngagementNoteView(
it.into(ENGAGEMENT_NOTE),
it.getValue("attendees") as List<EngagementNoteAttendeeRecord> // This is definitely wrong.
)
}
答案1
得分: 1
使用selectFrom(Table<R>)
来返回一个Result<R>
,而不是select().from(table)
。
jOOQ 3.19 解决方案
即将发布的jOOQ 3.19版本中,to-many path expressions和implicit path correlations将使这个过程非常简单:
context
.select(
// 你可以将Table<R>用作SelectField<R>
ENGAGEMENT_NOTE,
multiset(
// jOOQ 3.19 many-to-many implicit join path correlation
selectFrom(ENGAGEMENT_NOTE.engagementNoteAttendee())
).`as`("attendees")
.from(ENGAGEMENT_NOTE)
.where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
.fetchOne()
注意,上述代码还使用了Table<R>
作为SelectField<R>
。
jOOQ 3.18 解决方案
在jOOQ 3.18中,to-many path expressions和implicit path correlations尚不可用,因此您需要手动编写关联。例如,如果您的RDBMS支持关联派生表,您可以使用半连接:
context
.select(
ENGAGEMENT_NOTE,
multiset(
selectFrom(ENGAGEMENT_NOTE_ATTENDEE)
.where(ENGAGEMENT_NOTE_ATTENDEE.ID.in(
select(ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID)
.from(ENGAGEMENT_NOTE_ATTENDANCE)
.where(ENGAGEMENT_NOTE_ATTENDANCE.ENGAGEMENT_NOTE_ID
.eq(ENGAGEMENT_NOTE.ID))
))
).`as`("attendees")
.from(ENGAGEMENT_NOTE)
.where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
.fetchOne()
英文:
Use selectFrom(Table<R>)
to return a Result<R>
, instead of select().from(table)
.
jOOQ 3.19 solution
The upcoming jOOQ 3.19 to-many path expressions along with implicit path correlations will make this super simple:
context
.select(
// You can use a Table<R> as a SelectField<R>
ENGAGEMENT_NOTE,
multiset(
// jOOQ 3.19 many-to-many implicit join path correlation
selectFrom(ENGAGEMENT_NOTE.engagementNoteAttendee())
).`as`("attendees")
.from(ENGAGEMENT_NOTE)
.where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
.fetchOne()
Note, the above also uses a Table<R>
as a SelectField<R>
jOOQ 3.18 solution
In jOOQ 3.18, to-many path expressions and implicit path correlations aren't yet available, so you have to hand-roll the correlation. You could use a semi-join, for example, if your RDBMS supports correlating derived tables:
context
.select(
ENGAGEMENT_NOTE,
multiset(
selectFrom(ENGAGEMENT_NOTE_ATTENDEE)
.where(ENGAGEMENT_NOTE_ATTENDEE.ID.in(
select(ENGAGEMENT_NOTE_ATTENDANCE.ATTENDEE_ID)
.from(ENGAGEMENT_NOTE_ATTENDANCE)
.where(ENGAGEMENT_NOTE_ATTENDANCE.ENGAGEMENT_NOTE_ID
.eq(ENGAGEMENT_NOTE.ID))
))
).`as`("attendees")
.from(ENGAGEMENT_NOTE)
.where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
.fetchOne()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论