如何在JOOQ中为自动生成的枚举添加自定义属性?
如何为JOOQ自动生成的枚举添加自定义属性?
我们已从Hibernate迁移至JOOQ数月。此前在Hibernate中,我们会编写带自定义属性的枚举,实现枚举与GUI描述的1:1映射,还能添加表征行为的属性:
public enum HBMCapacityType { Accepting("Accepting until end of day", true), Limited("Limited until end of day", true), AtCapacity("At Capacity until further notice",false); private final String description; private final boolean userOverridable; HBMCapacityType(String description, boolean userOverridable) { this.description = description; this.userOverridable = userOverridable; } public String getDescription() { return this.description; } public boolean isUserOverridable() { return this.userOverridable; } }
并在Hibernate实体类中这样使用:
@Enumerated(EnumType.STRING) @Type(type = "pg_enum") @Column(name = "capacity_type", nullable = false, columnDefinition = "capacity_type") private HBMCapacityType capacityType;
但JOOQ会根据PostgreSQL中的枚举自动生成仅包含字面量的枚举:
/** * This class is generated by jOOQ. */ @SuppressWarnings({ "all", "unchecked", "rawtypes" }) public enum CapacityType implements EnumType { Accepting("Accepting"), Limited("Limited"), AtCapacity("AtCapacity"); private final String literal; private CapacityType(String literal) { this.literal = literal; } @Override public Catalog getCatalog() { return getSchema().getCatalog(); } @Override public Schema getSchema() { return Wastecoordinator.WASTECOORDINATOR; } @Override public String getName() { return "capacity_type"; } @Override public String getLiteral() { return literal; } /** * Lookup a value of this EnumType by its literal */ public static CapacityType lookupLiteral(String literal) { return EnumType.lookupLiteral(CapacityType.class, literal); } }
以下是几种为JOOQ自动生成的枚举添加自定义属性的可行方案:
方案一:自定义JOOQ代码生成策略
通过JOOQ的代码生成配置,修改枚举的生成逻辑,直接在生成的枚举类中添加自定义属性和方法:
- 在JOOQ的生成配置文件(如
jooq-codegen.xml)中配置自定义生成策略,继承DefaultGeneratorStrategy并重写generateEnum方法,或者使用Freemarker模板自定义枚举的生成模板。 - 在生成逻辑中加入
description、userOverridable等字段的定义,以及对应的构造方法和getter方法。
这种方式能让生成的枚举直接拥有所需属性,长期维护更便捷,无需额外工具类。
方案二:编写枚举扩展工具类
不修改自动生成的枚举,而是创建一个工具类来映射枚举值与自定义属性:
public class CapacityTypeExtensions { private static final Map<CapacityType, String> DESCRIPTION_MAP = Map.of( CapacityType.Accepting, "Accepting until end of day", CapacityType.Limited, "Limited until end of day", CapacityType.AtCapacity, "At Capacity until further notice" ); private static final Map<CapacityType, Boolean> OVERRIDABLE_MAP = Map.of( CapacityType.Accepting, true, CapacityType.Limited, true, CapacityType.AtCapacity, false ); public static String getDescription(CapacityType type) { return DESCRIPTION_MAP.get(type); } public static boolean isUserOverridable(CapacityType type) { return OVERRIDABLE_MAP.get(type); } }
使用时直接调用工具类方法:CapacityTypeExtensions.getDescription(capacityType),这种方式无需改动JOOQ生成逻辑,实现快速,适合临时需求或枚举值变动较少的场景。
方案三:利用Java接口默认方法
定义一个包含所需属性方法的接口,再让JOOQ生成的枚举实现该接口:
- 创建接口:
public interface CapacityTypeProperties { default String getDescription() { return switch ((CapacityType) this) { case Accepting -> "Accepting until end of day"; case Limited -> "Limited until end of day"; case AtCapacity -> "At Capacity until further notice"; }; } default boolean isUserOverridable() { return switch ((CapacityType) this) { case Accepting, Limited -> true; case AtCapacity -> false; }; } }
- 修改JOOQ生成配置,让自动生成的
CapacityType枚举实现CapacityTypeProperties接口(可通过自定义生成策略实现,避免每次生成后手动修改)。
这种方式代码更优雅,调用方式和Hibernate时期一致:capacityType.getDescription(),同时保留JOOQ自动生成的特性。
内容的提问来源于stack exchange,提问作者benstpierre
相关产品推荐
相关产品推荐

