如何从ModelMapper迁移到MapStruct?解决映射冗余与复用问题
MapStruct 常见问题解决方案
一、避免冗余@Mapping注解的方法
MapStruct本身默认支持同名属性自动映射,完全不需要给每个属性手动加@Mapping,只有当实体和DTO的属性名不一致、或者需要特殊转换逻辑时,才需要单独配置。
示例:同名属性自动映射
如果Tariff和TariffDTO的属性(比如id、name、price等)完全同名,直接定义映射接口即可:
@Mapper(componentModel = "spring") // 用spring组件模型,方便注入 public interface TariffMapper { TariffMapper INSTANCE = Mappers.getMapper(TariffMapper.class); // 所有同名属性自动完成映射,无需额外注解 TariffDTO toDto(Tariff tariff); }
仅处理差异属性
如果有个别属性名不同(比如实体里的createTime对应DTO里的createdAt),只需要给这一个属性加@Mapping,其余同名属性依然自动映射:
@Mapper(componentModel = "spring") public interface TariffMapper { TariffMapper INSTANCE = Mappers.getMapper(TariffMapper.class); @Mapping(source = "createTime", target = "createdAt") // 仅配置差异属性 TariffDTO toDto(Tariff tariff); }
二、复用独立的嵌套对象映射器
完全可以创建独立的EnergyMix到EnergyMixDTO的映射器,然后在Tariff的映射逻辑中复用,步骤如下:
1. 定义独立的EnergyMix映射器
@Mapper(componentModel = "spring") public interface EnergyMixMapper { EnergyMixMapper INSTANCE = Mappers.getMapper(EnergyMixMapper.class); EnergyMixDTO toDto(EnergyMix energyMix); }
2. 在Tariff映射器中复用
通过@Mapper注解的uses属性引入EnergyMixMapper,MapStruct会自动调用它来处理Tariff中的EnergyMix类型属性:
@Mapper(componentModel = "spring", uses = EnergyMixMapper.class) public interface TariffMapper { TariffMapper INSTANCE = Mappers.getMapper(TariffMapper.class); // 如果Tariff里有energyMix属性,TariffDTO里有对应的energyMixDTO属性,会自动用EnergyMixMapper转换 TariffDTO toDto(Tariff tariff); }
若嵌套属性名不同
如果Tariff中的属性名是energyMix,而TariffDTO中是energyMixInfo,只需补充一个@Mapping指定对应关系即可,MapStruct依然会复用已有的映射逻辑:
@Mapper(componentModel = "spring", uses = EnergyMixMapper.class) public interface TariffMapper { TariffMapper INSTANCE = Mappers.getMapper(TariffMapper.class); @Mapping(source = "energyMix", target = "energyMixInfo") TariffDTO toDto(Tariff tariff); }
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

