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

JOOQ实现Record Entity到含嵌套对象POJO的映射求助

用JOOQ实现带嵌套国家对象的CityDto查询

前提说明

假设你的表关联逻辑是:d_cities表通过外键(比如country_id)关联d_countries表的主键(比如id);JOOQ自动生成的实体类对应表对象为D_CITIES、D_COUNTRIES,实体类为DCities、DCountries。

实现方案

1. 确认CityDto结构

先确保你的DTO包含嵌套的国家对象,示例结构如下:

public class CityDto {
    private String id;
    private String name;
    private CountryDto country; // 嵌套的国家DTO

    // 构造器、getter、setter自行补充
}

public class CountryDto {
    private String id;
    private String name;

    // 构造器、getter、setter自行补充
}

2. 基于DSLContext的三种实现方式

方式一:手动映射(新手易理解)

直接通过查询结果逐字段映射到嵌套DTO:

public CityDto getCityById(String cityId) {
    // 执行关联查询
    Result<Record> result = dslContext.select()
        .from(D_CITIES)
        .join(D_COUNTRIES).on(D_CITIES.COUNTRY_ID.eq(D_COUNTRIES.ID))
        .where(D_CITIES.ID.eq(cityId))
        .fetch();

    if (result.isEmpty()) {
        return null; // 或根据业务抛出异常
    }

    Record record = result.get(0);

    // 映射国家对象
    CountryDto countryDto = new CountryDto();
    countryDto.setId(record.get(D_COUNTRIES.ID));
    countryDto.setName(record.get(D_COUNTRIES.NAME));

    // 映射城市对象并嵌套国家
    CityDto cityDto = new CityDto();
    cityDto.setId(record.get(D_CITIES.ID));
    cityDto.setName(record.get(D_CITIES.NAME));
    cityDto.setCountry(countryDto);

    return cityDto;
}

方式二:用Lambda简化映射

通过JOOQ的fetchOne()结合Lambda直接完成映射,代码更紧凑:

public CityDto getCityById(String cityId) {
    return dslContext.select()
        .from(D_CITIES)
        .join(D_COUNTRIES).on(D_CITIES.COUNTRY_ID.eq(D_COUNTRIES.ID))
        .where(D_CITIES.ID.eq(cityId))
        .fetchOne(record -> {
            CountryDto country = new CountryDto(
                record.get(D_COUNTRIES.ID),
                record.get(D_COUNTRIES.NAME)
            );
            return new CityDto(
                record.get(D_CITIES.ID),
                record.get(D_CITIES.NAME),
                country
            );
        });
}

方式三:复用JOOQ自动生成的DTO

如果你的JOOQ代码生成配置中开启了DTO生成(比如自动生成DCitiesDto、DCountriesDto),可以直接用into()方法转换后组装:

public CityDto getCityById(String cityId) {
    Record record = dslContext.select()
        .from(D_CITIES)
        .join(D_COUNTRIES).on(D_CITIES.COUNTRY_ID.eq(D_COUNTRIES.ID))
        .where(D_CITIES.ID.eq(cityId))
        .fetchOne();

    if (record == null) {
        return null;
    }

    // 用JOOQ自动生成的DTO转换
    DCitiesDto city = record.into(DCitiesDto.class);
    DCountriesDto country = record.into(DCountriesDto.class);

    // 组装自定义CityDto
    CityDto cityDto = new CityDto();
    cityDto.setId(city.getId());
    cityDto.setName(city.getName());
    cityDto.setCountry(new CountryDto(country.getId(), country.getName()));

    return cityDto;
}

注意事项

  • 替换代码中的字段名(如COUNTRY_ID、NAME)为你实际表中的字段,JOOQ自动生成的字段均为大写常量。
  • 若城市允许无关联国家(外键为null),需将join改为leftJoin,并处理国家对象为null的场景。
  • 性能优化:避免用select()查询全字段,可指定需要的字段,比如select(D_CITIES.ID, D_CITIES.NAME, D_COUNTRIES.ID, D_COUNTRIES.NAME)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:05:07