You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:54:02