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
相关产品推荐
相关产品推荐

