如何自定义MapStruct映射器,无需手动定义全部字段映射
解决MapStruct自定义指定字段映射、其余自动转换的方案
不用手动编写全量字段转换逻辑,MapStruct提供了几种简洁方式实现仅自定义指定字段处理、其余字段自动映射:
方案一:@Named + @Mapping(qualifiedByName)
适合单个字段需要独立自定义转换逻辑的场景:
- 在映射接口中定义带
@Named注解的自定义转换方法 - 通过
@Mapping的qualifiedByName指定该方法处理目标字段
示例代码:
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; import org.mapstruct.factory.Mappers; @Mapper public interface DtoMapper { DtoMapper INSTANCE = Mappers.getMapper(DtoMapper.class); // 处理字段命名差异,其余字段自动映射 @Mapping(target = "desiredName", source = "notDesiredName") // 指定something字段用自定义方法处理 @Mapping(target = "something", source = "something", qualifiedByName = "handleSomething") DTO1 toDto1(DTO2 dto2); // 自定义字段处理方法,用@Named标记 @Named("handleSomething") default String handleSomething(String originalValue) { // 自定义处理逻辑,比如格式转换、值映射等 return originalValue != null ? originalValue.toUpperCase() : null; } }
方案二:@AfterMapping + @MappingTarget
适合自动映射完成后对指定字段做额外处理的场景:
- 定义常规自动映射方法(包含字段命名差异的
@Mapping) - 新增带
@AfterMapping和@MappingTarget注解的方法,在自动映射后修改目标字段
示例代码:
import org.mapstruct.AfterMapping; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.factory.Mappers; @Mapper public interface DtoMapper { DtoMapper INSTANCE = Mappers.getMapper(DtoMapper.class); // 常规自动映射,处理字段命名差异 @Mapping(target = "desiredName", source = "notDesiredName") DTO1 toDto1(DTO2 dto2); // 自动映射完成后,处理指定字段 @AfterMapping default void handleSomethingAfterMapping(DTO2 source, @MappingTarget DTO1 target) { target.setSomething(myFunction(source.getSomething())); } // 自定义处理函数 default String myFunction(String value) { // 自定义逻辑 return value != null ? "processed_" + value : null; } }
方案三:@Mapping(expression)
适合自定义逻辑简单的场景,直接在注解中写表达式:
import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; @Mapper public interface DtoMapper { DtoMapper INSTANCE = Mappers.getMapper(DtoMapper.class); @Mapping(target = "desiredName", source = "notDesiredName") // 直接通过expression指定处理逻辑,可调用自定义方法或写简单逻辑 @Mapping(target = "something", expression = "java(myFunction(dto2.getSomething()))") DTO1 toDto1(DTO2 dto2); default String myFunction(String value) { return value != null ? value.trim() : null; } }
以上三种方式都无需手动编写所有字段的setter逻辑,MapStruct会自动生成其余字段的映射代码,只需专注处理需要自定义的字段即可。
内容的提问来源于stack exchange,提问作者Nanor
相关产品推荐
相关产品推荐

