Mapstruct如何实现String类型code与多类枚举的双向互转
解决方案
第一步:定义通用枚举基接口
先给所有带Code属性的枚举抽取公共接口,统一获取Code的方法:
public interface BaseEnum<T> { T getCode(); }
所有需要按Code匹配的枚举都实现该接口,示例:
public enum TxAccTypeDto implements BaseEnum<String> { FINANCE("Finance"); private final String code; TxAccTypeDto(String code) { this.code = code; } @Override public String getCode() { return code; } } public enum TxStatusDto implements BaseEnum<String> { PENDING("Pending"); private final String code; TxStatusDto(String code) { this.code = code; } @Override public String getCode() { return code; } }
第二步:实现通用枚举转换工具
封装通用的Code转枚举逻辑,支持任意实现了BaseEnum的枚举类型:
public class EnumConverterUtil { public static <E extends Enum<E> & BaseEnum<String>> E codeToEnum(String code, Class<E> enumClass) { if (code == null || enumClass == null) { return null; } for (E enumConstant : enumClass.getEnumConstants()) { if (code.equals(enumConstant.getCode())) { return enumConstant; } } // 匹配不到可根据业务需求返回null或抛异常 return null; } }
第三步:定义通用Mapstruct转换父接口
借助Mapstruct提供的@TargetType注解自动获取目标枚举类型,无需手动指定:
import org.mapstruct.TargetType; public interface BaseEnumMapper { // String转枚举:自动识别目标枚举类型,兼容带Code的枚举和普通枚举 default <E extends Enum<E>> E stringToEnum(String code, @TargetType Class<E> enumClass) { if (code == null) { return null; } // 优先匹配带Code的BaseEnum实现类枚举 if (BaseEnum.class.isAssignableFrom(enumClass)) { return EnumConverterUtil.codeToEnum(code, (Class<E & BaseEnum<String>>) enumClass); } // 普通枚举按枚举名称匹配(比如示例中的ContactMethod) try { return Enum.valueOf(enumClass, code); } catch (IllegalArgumentException e) { return null; } } // 可选:枚举反向转String,DTO转Entity时用 default <E extends Enum<E>> String enumToString(E enumValue) { if (enumValue == null) { return null; } if (enumValue instanceof BaseEnum<?>) { return (String) ((BaseEnum<?>) enumValue).getCode(); } return enumValue.name(); } }
第四步:业务Mapper直接继承使用
你的业务Mapper仅需继承BaseEnumMapper,无需额外配置单个字段的映射规则:
import org.mapstruct.Mapper; // 若使用Spring容器管理则加componentModel = "spring",否则去掉即可 @Mapper(componentModel = "spring") public interface TxMapper extends BaseEnumMapper { TxEntity toEntity(TxDto dto); TxDto toDto(TxEntity entity); }
效果验证
完全满足你的两个需求:
- 业务代码仅需调用
toEntity/toDto方法即可完成自动转换,无需传入额外参数 - 新增枚举类型时,带Code的枚举仅需实现
BaseEnum<String>接口,普通枚举无需任何改造,不用新增转换逻辑也不用修改Mapper配置
内容的提问来源于stack exchange,提问作者DSEyers
相关产品推荐
相关产品推荐

