如何使用multiset来获取与JOOQ关联的记录列表?

huangapple go评论86阅读模式
英文:

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`(&quot;attendees&quot;)
    )
        .from(ENGAGEMENT_NOTE)
        .where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
        .fetchOne()
        ?.map {
            EngagementNoteView(
                it.into(ENGAGEMENT_NOTE),
                it.getValue(&quot;attendees&quot;) as List&lt;EngagementNoteAttendeeRecord&gt; // This is definitely wrong.
            )
        }

答案1

得分: 1

使用selectFrom(Table&lt;R&gt;)来返回一个Result&lt;R&gt;,而不是select().from(table)

jOOQ 3.19 解决方案

即将发布的jOOQ 3.19版本中,to-many path expressionsimplicit path correlations将使这个过程非常简单:

context
    .select(

        // 你可以将Table&lt;R&gt;用作SelectField&lt;R&gt;
        ENGAGEMENT_NOTE,
        multiset(

            // jOOQ 3.19 many-to-many implicit join path correlation
            selectFrom(ENGAGEMENT_NOTE.engagementNoteAttendee())
        ).`as`(&quot;attendees&quot;)
    .from(ENGAGEMENT_NOTE)
    .where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
    .fetchOne()

注意,上述代码还使用了Table&lt;R&gt;作为SelectField&lt;R&gt;

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`(&quot;attendees&quot;)
    .from(ENGAGEMENT_NOTE)
    .where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
    .fetchOne()
英文:

Use selectFrom(Table&lt;R&gt;) to return a Result&lt;R&gt;, 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&lt;R&gt; as a SelectField&lt;R&gt;
        ENGAGEMENT_NOTE,
        multiset(

            // jOOQ 3.19 many-to-many implicit join path correlation
            selectFrom(ENGAGEMENT_NOTE.engagementNoteAttendee())
        ).`as`(&quot;attendees&quot;)
    .from(ENGAGEMENT_NOTE)
    .where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
    .fetchOne()

Note, the above also uses a Table&lt;R&gt; as a SelectField&lt;R&gt;

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`(&quot;attendees&quot;)
    .from(ENGAGEMENT_NOTE)
    .where(ENGAGEMENT_NOTE.ID.eq(noteId.value))
    .fetchOne()

huangapple
  • 本文由 发表于 2023年8月9日 05:29:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863313.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定