如何通过MapStruct声明式实现基于LegType的Leg到TripLeg映射?
MapStruct声明式实现Leg到TripLeg的动态字段填充
针对你的需求,确实可以通过声明式注解实现根据Leg.type填充TripLeg对应字段的逻辑,无需依赖装饰器的自定义代码,具体方案如下:
方案一:使用@Mapping的expression属性
直接在映射接口中通过expression属性编写条件判断,根据Leg.type的值选择对应的子映射方法,其余字段置为null:
@Mapper public interface LegMapper { LegMapper INSTANCE = Mappers.getMapper(LegMapper.class); @Mapping(target = "timedLeg", expression = "java(leg.getType() == LegType.TIMED ? mapToTimedLeg(leg) : null)") @Mapping(target = "transferLeg", expression = "java(leg.getType() == LegType.TRANSFER ? mapToTransferLeg(leg) : null)") @Mapping(target = "continuousLeg", expression = "java(leg.getType() == LegType.CONTINUOUS ? mapToContinuousLeg(leg) : null)") TripLeg legToTripLeg(Leg leg); // MapStruct自动生成Leg到各子Leg类型的映射逻辑,可按需添加@Mapping自定义字段映射 TimedLeg mapToTimedLeg(Leg leg); TransferLeg mapToTransferLeg(Leg leg); ContinuousLeg mapToContinuousLeg(Leg leg); }
说明:
- 所有映射规则通过注解声明,属于纯声明式实现,无需额外装饰器类;
- 子映射方法可由MapStruct自动生成,若需要自定义字段映射,直接在对应方法上添加
@Mapping注解即可。
方案二:结合默认方法封装判断逻辑(更易维护)
如果觉得expression中的重复代码不够优雅,可以在映射接口中定义默认方法封装判断逻辑,再通过@Named和qualifiedByName关联映射规则:
@Mapper public interface LegMapper { LegMapper INSTANCE = Mappers.getMapper(LegMapper.class); @Mapping(target = "timedLeg", source = "leg", qualifiedByName = "timedLegCondition") @Mapping(target = "transferLeg", source = "leg", qualifiedByName = "transferLegCondition") @Mapping(target = "continuousLeg", source = "leg", qualifiedByName = "continuousLegCondition") TripLeg legToTripLeg(Leg leg); TimedLeg mapToTimedLeg(Leg leg); TransferLeg mapToTransferLeg(Leg leg); ContinuousLeg mapToContinuousLeg(Leg leg); @Named("timedLegCondition") default TimedLeg mapTimedLegConditionally(Leg leg) { return leg.getType() == LegType.TIMED ? mapToTimedLeg(leg) : null; } @Named("transferLegCondition") default TransferLeg mapTransferLegConditionally(Leg leg) { return leg.getType() == LegType.TRANSFER ? mapToTransferLeg(leg) : null; } @Named("continuousLegCondition") default ContinuousLeg mapContinuousLegConditionally(Leg leg) { return leg.getType() == LegType.CONTINUOUS ? mapToContinuousLeg(leg) : null; } }
说明:
- 逻辑封装在默认方法中,映射规则仍通过注解声明,属于声明式实现范畴;
- 后续修改判断逻辑时,只需调整对应默认方法,映射接口的注解结构无需变动,更易维护。
以上两种方案均无需使用装饰器,完全基于MapStruct的原生注解特性实现需求,符合声明式编程的要求。
内容的提问来源于stack exchange,提问作者jspetrak
相关产品推荐
相关产品推荐

