以多对多(Book_Author)关系中的book和Author表的常见示例为例.如果我想获取每个作者ID的图书列表,特别是使用multiset*,基于this example ,我希望它看起来如下所示:

select(
        AUTHOR.ID,
        multiset(
            select(BOOK_AUTHOR.book())
            .from(BOOK_AUTHOR)                                        
            .where(BOOK_AUTHOR.AUTHOR_ID.eq(AUTHOR.ID)))
            .as("books").convertFrom(r -> r.map(mapping(Book::new)))
        .from(AUTHOR)
        .fetchMap(...)

但映射器收到Record1<BookRecord>个,而预期为BookRecord个.因此,我不得不编写嵌套映射:

dsl.select(
        AUTHOR.ID,
        multiset(
            select(BOOK_AUTHOR.book())
            .from(BOOK_AUTHOR)
            .where(BOOK_AUTHOR.AUTHOR_ID.eq(AUTHOR.ID)))
            .as("books")
            //? seems wrong
            .convertFrom(r -> r.map(mapping((b) -> mapping(Book::new).apply(b)))))
        .from(AUTHOR)
        .fetchMap(AUTHOR.ID, mapping((a, b) -> b));

这是表达这个多集查询的最直接/最明显的方式吗?

编辑:

以下是我在得到earlier question个答案后的改进版本(尽管仍不是示例中promise 的):

dsl.select(
    AUTHOR.ID,
    multiset(
            select(BOOK_AUTHOR.book().mapping(Book::new)) //?
            .from(BOOK_AUTHOR)
            .where(BOOK_AUTHOR.AUTHOR_ID.eq(AUTHOR.ID)))
            .as("books").convertFrom(r -> r.map(Record1::value1)))
    .from(AUTHOR)
    .fetchMap(AUTHOR.ID, Record2::value2);

*我知道我在这里并不真的需要多集.这是我关于POJO分组的previous question个副产品,我只是在探索各种 Select .

推荐答案

为什么这些记录会嵌套

与泛型相关的任何问题的根本问题位于以下位置:

select(BOOK_AUTHOR.book())

您在SELECT子句中嵌套了一个BookRecord,有效地生成了一个类型为Select<Record1<BookRecord>>的子查询,而您预期的结果是:Select<BookRecord>.也就是说,您可能希望得到一个"平面"结果,而不是嵌套的结果.也许,如果您在投影中添加更多的列,会更有意义?例如,如果您这样做:

select(BOOK_AUTHOR.BOOK_ID, BOOK_AUTHOR.book())

那么更明显的是,您的结果类型是Select<Record2<Long, BookRecord>>.

如何避免嵌套

显然,在您的特定示例中,您希望:

  • 没有这种不必要的嵌套
  • BOOK_AUTHOR.book()中的隐式联接中获利

将提供Starting from jOOQ 3.19,to-many个路径表达式,包括FROM子句中的显式路径表达式:

  • #13639添加对多路径表达式的支持
  • #14985允许指定显式路径联接

然后就可以写成这样的东西了:

multiset(
  selectFrom(AUTHOR.book()) // Implicit correlation here on many-to-many relationship
)

// Simple mapping available now:
.convertFrom(r -> r.map(mapping(Book::new)))

这里的关键是,selectFrom()生成类型安全的TableRecord(在本例中为BookRecord),但不嵌套它.

In jOOQ 3.18 or less,这还不可用,所以您的2个变通方法可能是最简单的方法,因为您知道这种情况的出现是因为您在SELECT中嵌套记录.

显然,您总是可以通过明确地拼写出投影来避免嵌套:

multiset(
  select(BOOK_AUTHOR.book().ID, BOOK_AUTHOR.book().TITLE, ...)
  ...
)

在这种情况下,这个问题将被避免.虽然您想要的方法会很方便,但它也可能投影太多的柱.你真的需要所有的人吗?开销(内存消耗、传输等)可能很大.

Java相关问答推荐

收听RDX中用户数据的变化

Springdoc Whitelabel Error Page with Spring V3

Javascript在边界中心调整ImageView大小

从技术上讲,OPC UA客户端是否可以通过转发代理将请求通过 tunel 发送到OPC UA服务器?

使用动态ID从json获取详细信息的Jolt规范

如何在带有Micronaut的YAML中使用包含特殊字符的字符串作为键

关于泛型的覆盖规则

我找不到&Quot;配置&的位置

为什么我的在一个范围内寻找素数的程序不能像S所期望的那样工作

通过移动一个类解决了潜在的StubbingProblem.它怎麽工作?

自定义批注的外推属性值

Java构造函数分支

错误:不兼容的类型:Double不能转换为Float

我如何为我的Java抵押贷款代码执行加薪操作(&Q)

FETCH类型设置为LAZY,但它仍会发送第二个请求

深度优先搜索实现:算法只向右搜索

在权限列表中找不到我的应用程序

Java 21内置http客户端固定运营商线程

[Guice/MissingImplementation]:未绑定任何实现

将天数添加到ZonedDateTime不会更改时间