Mapstruct单个源字段映射多个目标字段的优雅实现方案咨询
更优雅的实现方案如下
方案1:MapStruct 1.5+ 原生多态映射+条件赋值(推荐)
MapStruct 1.5及以上版本支持condition属性实现条件映射,搭配原生的多态方法匹配能力,可以完全消除手动instanceof分支:
首先重构TypeMapper,无需手动判断类型,直接声明各子类的映射方法:
@Mapper public interface TypeMapper { StringType fhirToMpi(org.hl7.fhir.r4.model.StringType fhirType); BooleanType fhirToMpi(org.hl7.fhir.r4.model.BooleanType fhirType); CodeableConcept fhirToMpi(org.hl7.fhir.r4.model.CodeableConcept fhirType); }
然后改造ExtensionMapper,给每个目标字段指定匹配条件:
@Mapper(uses = TypeMapper.class) public interface ExtensionMapper { @Mapping(target = "valueString", source = "value", condition = "isStringType") @Mapping(target = "valueBoolean", source = "value", condition = "isBooleanType") @Mapping(target = "valueCodeableConcept", source = "value", condition = "isCodeableConcept") ExtensionTarget fhirToMpi(ExtensionSource fhirType); default boolean isStringType(Type value) { return value instanceof org.hl7.fhir.r4.model.StringType; } default boolean isBooleanType(Type value) { return value instanceof org.hl7.fhir.r4.model.BooleanType; } default boolean isCodeableConcept(Type value) { return value instanceof org.hl7.fhir.r4.model.CodeableConcept; } }
优势:
- 完全移除手动
if-else分支,类型匹配、Mapper实例注入全部由框架自动处理 - 后续新增
Type子类时,只需要新增对应映射方法和条件判断即可,符合开闭原则 - 各方法职责单一,可读性和可维护性更高
方案2:兼容MapStruct 1.4及以下版本,使用表达式实现
如果使用的是低版本MapStruct不支持condition属性,可以直接在expression中完成类型判断和赋值:
@Mapper( uses = TypeMapper.class, imports = { org.hl7.fhir.r4.model.StringType.class, org.hl7.fhir.r4.model.BooleanType.class, org.hl7.fhir.r4.model.CodeableConcept.class } ) public interface ExtensionMapper { @Mapping(target = "valueString", expression = "java(fhirType.getValue() instanceof StringType ? typeMapper.fhirToMpi((StringType) fhirType.getValue()) : null)") @Mapping(target = "valueBoolean", expression = "java(fhirType.getValue() instanceof BooleanType ? typeMapper.fhirToMpi((BooleanType) fhirType.getValue()) : null)") @Mapping(target = "valueCodeableConcept", expression = "java(fhirType.getValue() instanceof CodeableConcept ? typeMapper.fhirToMpi((CodeableConcept) fhirType.getValue()) : null)") ExtensionTarget fhirToMpi(ExtensionSource fhirType); }
对比原有实现的优化点
- 无需手动调用
Mappers.getMapper获取实例,框架会自动处理uses声明的Mapper依赖 - 移除冗长的类型判断分支,代码逻辑更直观
- 扩展新类型时不需要修改原有映射逻辑,维护成本更低
内容的提问来源于stack exchange,提问作者Jordi
相关产品推荐
相关产品推荐

