如何通过SQL查询配置jOOQ Embeddable Types代码生成映射规则
jOOQ自动映射同规则嵌入式类型的最优配置方案
核心思路:利用jOOQ代码生成器的可编程扩展接口,基于你的统一字段命名规则自动匹配字段组、注册嵌入式类型映射,无需逐表逐字段手动配置,可支撑数百张表的批量处理。
前置准备:定义通用嵌入式POJO
首先定义所有同类型嵌入式字段共用的Java值类,示例如下:
public class AmountWithUnit { private final Integer amount; private final String unit; // 全参数构造器、getter方法、equals、hashCode、toString 按需实现即可 public AmountWithUnit(Integer amount, String unit) { this.amount = amount; this.unit = unit; } public Integer getAmount() { return amount; } public String getUnit() { return unit; } }
自定义代码生成器逻辑
继承jOOQ默认的JavaGenerator类,在生成代码前遍历所有表的字段,按你的命名规则自动分组注册嵌入式类型,示例逻辑适配你给出的表结构规则:
import org.jooq.codegen.JavaGenerator; import org.jooq.meta.*; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class AutoEmbeddableGenerator extends JavaGenerator { @Override protected void generateSchema(SchemaDefinition schema) { // 遍历当前Schema下所有表 for (TableDefinition table : schema.getTables()) { // 过滤所有金额、单位相关字段,按后缀分组 // 规则:amount、unit为无后缀组,amount_pend、unit_pend为_pend后缀组 Map<String, List<ColumnDefinition>> embeddableGroups = table.getColumns().stream() .filter(col -> col.getName().matches("^(amount|unit)(_.*)?$")) .collect(Collectors.groupingBy(col -> { String colName = col.getName(); return colName.startsWith("amount") ? colName.replaceFirst("^amount", "") : colName.replaceFirst("^unit", ""); })); // 为每个分组注册嵌入式类型 embeddableGroups.forEach((suffix, columns) -> { if (columns.size() == 2) { // 确认分组同时包含amount和unit两个字段 EmbeddableDefinition embeddable = new EmbeddableDefinition( schema, table, "AMOUNT_WITH_UNIT" + suffix.toUpperCase(), // 生成的嵌入式字段名 columns.stream().map(ColumnDefinition::getName).toList(), AmountWithUnit.class.getName() // 绑定前置定义的通用POJO ); table.addEmbeddable(embeddable); } }); } // 执行默认的代码生成逻辑 super.generateSchema(schema); } }
配置构建工具使用自定义生成器
以Maven为例,在jOOQ代码生成插件的配置中指定自定义生成器类即可:
<plugin> <groupId>org.jooq</groupId> <artifactId>jooq-codegen-maven</artifactId> <version>你的jOOQ版本号</version> <configuration> <generator> <!-- 替换为你自定义的生成器全类名 --> <name>com.yourpackage.AutoEmbeddableGenerator</name> <!-- 其余原有配置(数据库连接、生成路径等)保持不变 --> <database> <!-- 原有数据库配置 --> </database> <target> <!-- 原有生成路径配置 --> </target> </generator> </configuration> </plugin>
生成效果验证
针对你给出的示例表t:
create table t(amount int, unit varchar2(4), amount_pend int, unit_pend varchar(4));
代码生成后会自动在表类中生成两个嵌入式字段:
T.AMOUNT_WITH_UNIT对应amount+unit字段组T.AMOUNT_WITH_UNIT_PEND对应amount_pend+unit_pend字段组
你可以直接操作整个嵌入式对象,无需单独处理单个字段:
// 写入示例 ctx.insertInto(T) .set(T.AMOUNT_WITH_UNIT, new AmountWithUnit(100, "CNY")) .set(T.AMOUNT_WITH_UNIT_PEND, new AmountWithUnit(50, "CNY")) .execute(); // 查询示例 AmountWithUnit normalAmount = ctx.select(T.AMOUNT_WITH_UNIT) .from(T) .fetchOneInto(AmountWithUnit.class);
该方案完全适配批量表场景,只要字段命名规则保持统一,后续新增表、新增同规则嵌入式字段都无需修改配置,自动生成映射。
内容的提问来源于stack exchange,提问作者Alf
相关产品推荐
相关产品推荐

