如何在MapStruct中查找源与目标属性映射关系以适配动态查询需求
MapStruct实现属性映射关系查询的可行方案
MapStruct是编译期生成映射代码的框架,默认不会在运行时保留类似ModelMapper TypeMap的元数据,但可以通过以下两种方式实现属性对应关系查询的需求:
方案1:使用官方元数据模块(推荐,适用于MapStruct 1.5+版本)
MapStruct官方提供了mapstruct-metadata模块,支持编译期生成映射元数据,运行时直接查询即可:
- 引入对应依赖,在Mapper接口上添加
@GenerateMetadata注解开启元数据生成:
@Mapper @GenerateMetadata public interface PersonMapper { PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class); @Mapping(source = "contact.address.line1", target = "contactAddressLine1") PersonEntity domainToEntity(PersonDomain domain); }
- 运行时通过元数据类查询属性对应关系:
// 获取Mapper对应的元数据实例 MappingMetadata mapperMetadata = MappingMetadata.forMapper(PersonMapper.class); // 获取指定映射方法的元数据 MappingMethodMetadata methodMeta = mapperMetadata.forMethod("domainToEntity", PersonDomain.class, PersonEntity.class); // 目标属性查对应源属性 Optional<String> sourcePath = methodMeta.getMappings().stream() .filter(mapping -> "contactAddressLine1".equals(mapping.getTargetName())) .map(MappingMetadata::getSourceName) .findFirst(); // 源属性查对应目标属性 Optional<String> targetPath = methodMeta.getMappings().stream() .filter(mapping -> "contact.address.line1".equals(mapping.getSourceName())) .map(MappingMetadata::getTargetName) .findFirst();
该方案适配嵌套映射、自定义转换等绝大多数场景,元数据编译期生成,运行时查询无额外性能开销。
方案2:自定义注解处理器生成映射对照表
如果使用的MapStruct版本低于1.5,也可以自定义一个轻量的注解处理器,在编译阶段扫描所有@Mapping注解,自动生成每个映射对的双向属性映射常量Map,运行时直接查询常量即可,示例生成的常量类结构如下:
public final class PersonMappingConstants { public static final Map<String, String> TARGET_TO_SOURCE = Map.ofEntries( Map.entry("contactAddressLine1", "contact.address.line1"), // 其他映射字段自动生成 ); public static final Map<String, String> SOURCE_TO_TARGET = TARGET_TO_SOURCE.entrySet().stream() .collect(Collectors.toUnmodifiableMap(Map.Entry::getValue, Map.Entry::getKey)); }
内容的提问来源于stack exchange,提问作者Craig Archer
相关产品推荐
相关产品推荐

