jOOQ 多层嵌套

问题描述 投票:0回答:1

我正在尝试使用 jOOQ 从数据库中获取复杂的结构。我将尝试解释问题所在的示例。

所以,假设我们有类 Foo、Bar 和 Bazz:

public class Foo {
    private String fooName;
    private List<Bar> bars;
}

public class Bar {
    private Bazz bazz;
}

public class Bazz {
    private String name;
}

我想获取并填充 Foo -> List -> Bazz 关系。

我试过

MULTISET
并且它有效,但我想避免子查询。我想使用
JOIN
获取和映射它。我想知道是否有可能使用反射来获取它,比如this.

这是

MULTISET
的例子:

public List<FooResponse> findByFooName(String fooName) {
        return ctx().select(FOO.asterisk(),
                        multiset(select(BAR.asterisk(),
                                BAR.bazz().as("bazz"))
                              .from(BAR)
                              .where(BAR.FOO_ID.eq(FOO.ID))).as("bars"))
        .from(FOO)
        .where(FOO.FOO_NAME.eq(fooName))
        .fetchInto(FooResponse.class);
    }
java spring postgresql spring-boot jooq
1个回答
0
投票

在您的特定情况下,您可以使用

JOIN
GROUP BY
/
MULTISET_AGG
嵌套,而不是使用
MULTISET
值构造函数
,因为您只嵌套了一层嵌套集合(第二层嵌套不是集合)。主要区别在于当您没有任何
BAR
FOO
时会发生什么。通过聚合,这会产生一个
NULL
值,而不是一个空集合。

但是,API 中存在一些限制(例如 #15007#13937),这使得使用

DefaultRecordMapper
fetchInto(X.class)
调用)有点困难。这是使用 ad-hoc 转换 和类型安全的解决方案:

ctx().select(
        FOO.FOO_NAME,
        multisetAgg(

          // Add more BAR columns here, if needed
          row(

            // Add more BAZZ columns here, if needed
            BAR.bazz().NAME
          ).mapping(Bazz::new)
        ).convertFrom(r -> r.map(Records.mapping(Bar::new)))
      )
     .from(FOO)
     .join(BAR).on(BAR.FOO_ID.eq(FOO.ID))
     .groupBy(FOO.ID)
     .where(FOO.FOO_NAME.eq(fooName))
     .fetch(Records.mapping(Foo::new));

这是假设你有相关的构造函数。如果你不这样做,你可以随时恢复到每个级别的

into(X.class)
电话。

使用 jOOQ 的代码生成器 的一个好处是您拥有类型安全的嵌套集合映射,如上所示。

© www.soinside.com 2019 - 2024. All rights reserved.