从JPA迁移至jOOQ:如何实现Encodable枚举的通用持久化?
jOOQ实现Encodable枚举的通用持久化方案
当然可以实现类似JPA的通用枚举转换,不需要为每个枚举单独配置<forcedType>。以下是具体实现步骤:
1. 编写通用Converter
实现jOOQ的Converter<Integer, E>接口,封装Encodable枚举和数据库int类型的转换逻辑:
import org.jooq.Converter; import java.util.Arrays; public class EncodableConverter<E extends Enum<E> & Encodable> implements Converter<Integer, E> { private final Class<E> enumType; public EncodableConverter(Class<E> enumType) { this.enumType = enumType; } @Override public E from(Integer code) { if (code == null) return null; return Arrays.stream(enumType.getEnumConstants()) .filter(enumVal -> enumVal.getCode() == code) .findFirst() .orElseThrow(() -> new IllegalArgumentException("无效枚举code: " + code)); } @Override public Integer to(E enumVal) { return enumVal != null ? enumVal.getCode() : null; } @Override public Class<Integer> fromType() { return Integer.class; } @Override public Class<E> toType() { return enumType; } }
2. 配置jOOQ代码生成器
在代码生成配置中,添加一个通用的<forcedType>配置,通过正则匹配所有实现Encodable接口的枚举,并自动应用转换器:
<generator> <database> <!-- 你的数据库连接、Schema等配置 --> </database> <generate> <!-- 生成实体、DAO等配置 --> </generate> <forcedTypes> <forcedType> <!-- 正则匹配你的枚举所在包下的所有类,根据实际路径调整 --> <includeExpression>com\.yourcompany\.enums\..+</includeExpression> <!-- 指定枚举的父接口类型 --> <userType>com.yourcompany.Encodable</userType> <!-- 指定通用转换器的全类名 --> <converter>com.yourcompany.EncodableConverter</converter> <!-- 自动应用到所有匹配的类型,无需逐个枚举配置 --> <autoApply>true</autoApply> </forcedType> </forcedTypes> </generator>
关键注意事项
- 确保所有枚举类都正确实现
Encodable接口,包含int getCode()方法。 - 调整
<includeExpression>的正则表达式,匹配你项目中枚举类的实际包路径。 - 如果数据库中对应的字段是
SMALLINT等其他整数类型,需要修改Converter的fromType()为对应的包装类(如Short.class),并在<forcedType>中添加<includeTypes>SMALLINT</includeTypes>匹配数据库类型。
这个配置的效果和JPA中autoApply=true的通用转换器完全一致,一次配置即可适配所有实现Encodable的枚举,无需重复编写50多份配置。
内容的提问来源于stack exchange,提问作者wuttke
相关产品推荐
相关产品推荐

