You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jooq将子表查询关联的父表行转换为Java Record

解决jOOQ查询多对一关系并映射到嵌套Java Record的问题

问题回顾

你有两张多对一关系的表:

CREATE TABLE parent (
  id BIGINT PRIMARY KEY,
  name VARCHAR(255)
)

CREATE TABLE child (
  id BIGINT PRIMARY KEY,
  name VARCHAR(255),
  parent_id BIGINT FOREIGN KEY REFERENCES parent (id)
)

希望查询child表时,将关联的parent行自动转换为Java Record,之前的代码存在关联方向错误,且未正确使用转换方法。

正确实现方案

1. 先定义对应的Java Record

假设你需要以下两个Record类:

public record Parent(Long id, String name) {}
public record ChildDTO(Long id, String name, Parent parent) {}

2. 方案一:使用嵌套的Records.mapping(最简洁推荐)

jOOQ的Records.mapping支持直接嵌套构造函数映射,无需手动处理行转换:

var result = dslContext.select(
        CHILD.ID,
        CHILD.NAME,
        PARENT.ID,
        PARENT.NAME
    )
    .from(CHILD)
    // 正确关联方向:从Child关联对应的Parent
    .join(PARENT).on(CHILD.PARENT_ID.eq(PARENT.ID))
    // 嵌套映射:先构造Parent实例,再传入ChildDTO构造函数
    .fetch(Records.mapping(ChildDTO::new, Parent::new));

这里jOOQ会自动将前两个字段绑定到ChildDTO的前两个参数,后两个字段绑定到Parent的构造函数,再把生成的Parent实例作为第三个参数传给ChildDTO。

3. 方案二:显式使用row().convert()转换

如果你希望手动构造Parent的行记录并转换,可以用row(...).convert()方法:

var result = dslContext.select(
        CHILD.ID,
        CHILD.NAME,
        // 把Parent的字段包装成行,直接转换为Parent Record
        DSL.row(PARENT.ID, PARENT.NAME).convert(Parent::new)
    )
    .from(CHILD)
    .join(PARENT).on(CHILD.PARENT_ID.eq(PARENT.ID))
    // 直接用ChildDTO的构造函数接收三个参数
    .fetch(Records.mapping(ChildDTO::new));

关键错误修正

你之前的代码用了PARENT.child(),这是从Parent关联所有Child的一对多方向,但你需要的是从Child关联单个Parent的多对一查询,所以必须从CHILD表出发,关联PARENT表,而不是反过来。

内容的提问来源于stack exchange,提问作者Kevin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 21:41:10