当前位置: 首页 > 知识库问答 >
问题:

jOOQ-DefaultRecordMapper-列表

龙德海
2023-03-14

DefaultRecordMapper可以处理列表吗?

模型示例(实际使用了getter/setter):

class Head {
    public Integer id;
    public List<Position> positions;
    ...
}
class Position {
    public Integer id;
    public Integer headId;
    ...
}

我首先用一个简单的选择进行了尝试:

dsl.select()
    .from(HEAD)
    .join(POSITION).onKey()
    .fetchInto(Head.class);

我也尝试过使用嵌套语法,但没有成功:

dsl.select(..., POSITION.ID.as("positions.id"), ...)
    .from(HEAD)
    .join(POSITION).onKey()
    .fetchInto(Head.class);

列表永远不会初始化。我不确定我是否做错了什么。DefaultRecordMapper可以做到这一点吗?

我知道jOOQ提供了“intoGroups”之类的功能。然而,这意味着我们公司不能使用我们现有的模型。

或者在这种情况下是否需要像ModelMapper这样的第三方库?

非常感谢提前!

共有1个答案

庄智
2023-03-14

jOOQ中对嵌套集合的现成支持是通过SQL/XML或SQL/JSON实现的,这取决于在SQL方言中最有效的方式。

从jOOQ 3.14开始,这是作为一个API提供的,您可以直接使用,在jOOQ 3.15中,添加了新的MULTISETMULTISET_AGG函数,以保持序列化格式对您的代码透明,并重新添加类型安全,另请参阅这篇博文。

其思想是直接在SQL中嵌套集合,将结果序列化为XML或JSON,并在后台使用JAXB(用于XML)、Gson或Jackson(用于JSON)将文档映射到Java类的层次结构中。只要您的类路径上有JAXB、Gson或Jackson,所有这些都是非常直接和自动的。

数据结构示例:

dsl.select(
      HEAD.ID,
      field(
        select(jsonArrayAgg(jsonObject(
          key("id").value(POSITION.ID),
          key("x").value(POSITION.X), ...
        )))
        .from(POSITIONS)
        .where(POSITIONS.HEAD_ID.eq(HEAD.ID))
      ).as("positions")
    )
    .from(HEAD)
    .fetchInto(Head.class);

此处记录了更多示例:

  • https://blog.jooq.org/2020/10/09/nesting-collections-with-jooq-3-14s-sql-xml-or-sql-json-support/

请注意,JSON\u ARRAYAGG()将空集聚合为空集,而不是空集。如果这是一个问题,请使用COALESCE()

从jOOQ 3.15开始,建议使用多集。您的查询现在看起来是这样的(都是类型安全的!)

dsl.select(
      HEAD.ID,
      multiset(
        select(POSITION.ID, POSITION.X, ...)
        .from(POSITIONS)
        .where(POSITIONS.HEAD_ID.eq(HEAD.ID))
      ).convertFrom(r -> r.map(Records.mapping(Position::new)))
    )
    .from(HEAD)
    .fetch(Records.mapping(Head::new));

以上假设您的类型上有适当的构造函数,以便从新的ad-hoc转换器特性中获益。

还有一些第三方可以帮助简化映射到嵌套集合的任务,包括:

  • SimpleFlatMapper

或者,在某种程度上,您可以使用jOOQ的各种内置方法,包括结果的许多重载。intoGroups()或基于JDK的结果查询。collect(),它更易于组合。

这些方法中的大多数只在一定程度上起作用,因为它们都基于对连接表产生的平坦、非规范化结果集进行重复消除。直接在SQL中嵌套集合对于任意目标模型来说功能强大得多,所以如果你能做到这一点,它会工作得更好。

 类似资料:
  • 目前我正在从pojos列表映射到记录,我希望能够一次插入多行。我如何在JOOQ中用一个事务做到这一点? 我曾尝试将列表放入“值”中,但出现异常“值的数量必须与字段的数量匹配”

  • 我一直在使用模式。方法来获取模式中的表列表,但今天我发现该方法返回的是执行jOOQ代码生成时存在的表列表,而不是此时存在的表。 我的具体用例是随着时间的推移创建表(自动分区),我们的Java服务对它们执行一些操作。 在jOOQ中有没有办法从DB中获取当前的表列表? 我可以求助于查询信息模式。直接使用表,但我更愿意重用来自jOOQ的方法(如果可用的话)。

  • 在我的oracle数据库中,在表中,我有一个日期列。我使用jooq获取它,这是一个简单的选择查询。jooq获取列值,但没有时间。我错过了什么配置吗?

  • jOOQ可以将查询结果映射到POJO中的多个嵌套列表吗?例如,我有一个POJO VM,它代表一个虚拟机。它具有'networks'属性,这是一个类型为network的列表。它还有一个'hdds'属性,这是一个类型为'hdd'的列表。该查询连接VM、HDD和Networks表。我是否可以“获取”到vm.class并期望jOOQ“做正确的事情”?

  • jOOQ 高效的合并了复杂 SQL、类型安全、源码生成、Active Records、存储过程以及高级数据类型的 Java 类库。 示例代码: // Create a new record and insert it into the databaseTBookRecord book = create.newRecord(T_BOOK);book.setTitle("My first book")

  • 我想以某种方式将模式中的一列标记为“deprecated”(可能是列注释中的某种标记或其他标记),然后在代码生成过程中使该信息冒泡出来,从而在生成的代码中向该列的字段/方法添加一个注释。 JOOQ有任何与此相关的功能吗<浏览用户手册似乎没有显示任何相关内容。