MapStruct:如何根据源内容动态切换映射目标?
MapStruct 按国家区分州/省映射方案
针对你遇到的国际地址映射需求,这里提供两种实用的实现方式:
方法1:利用@Condition注解实现条件映射
通过定义条件判断方法,让MapStruct根据国家字段的值决定是否映射到state或province字段:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface AddressMapper { AddressMapper INSTANCE = Mappers.getMapper(AddressMapper.class); // 判断是否为美国的条件方法 @Condition default boolean isUSA(String country) { return "USA".equals(country); } // 判断是否非美国的条件方法 @Condition default boolean isNotUSA(String country) { return !"USA".equals(country); } @Mapping(target = "userCountry", source = "Form_User_Country") // 仅当国家为USA时,映射州字段 @Mapping(target = "userState", source = "Form_User_State_or_Province", condition = "#{isUSA(source.Form_User_Country)}") // 仅当国家非USA时,映射省字段 @Mapping(target = "userProvince", source = "Form_User_State_or_Province", condition = "#{isNotUSA(source.Form_User_Country)}") UserAddressDto mapFormToDto(FormAddress formAddress); }
当Form_User_Country为USA时,userState会被赋值,userProvince因条件不满足保持默认值;反之则userProvince赋值,userState为空。
方法2:自定义映射方法(更直观)
直接编写默认方法手动处理映射逻辑,适合需要灵活控制的场景:
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface AddressMapper { AddressMapper INSTANCE = Mappers.getMapper(AddressMapper.class); default UserAddressDto mapFormToDto(FormAddress formAddress) { if (formAddress == null) { return null; } UserAddressDto dto = new UserAddressDto(); // 映射国家字段 dto.setUserCountry(formAddress.getForm_User_Country()); String stateOrProvince = formAddress.getForm_User_State_or_Province(); // 根据国家判断映射到州还是省 if ("USA".equals(formAddress.getForm_User_Country())) { dto.setUserState(stateOrProvince); } else { dto.setUserProvince(stateOrProvince); } // 若有其他字段需要自动映射,可调用MapStruct生成的部分映射方法 // mapRemainingFields(formAddress, dto); return dto; } // 可选:定义其他字段的自动映射方法,在上面的默认方法中调用 // void mapRemainingFields(FormAddress formAddress, @MappingTarget UserAddressDto dto); }
这种方式完全掌控映射逻辑,后续扩展更方便。
注意事项
- 确保
FormAddress和UserAddressDto类存在对应的getter/setter方法,MapStruct依赖这些方法生成映射代码。 - 添加
unmappedTargetPolicy = ReportingPolicy.IGNORE可以避免未映射字段的编译警告。
内容的提问来源于stack exchange,提问作者trypophobe
相关产品推荐
相关产品推荐

