MapStruct多扁平源转多相同目标映射问题求助
解决方案
1. 调整WheelMapper,添加上下文参数和字段获取逻辑
修改WheelMapper,让映射方法接收BikeDTO和代表轮号的上下文参数,通过默认方法根据轮号返回对应字段的值:
@Mapper public interface WheelMapper { WheelMapper INSTANCE = Mappers.getMapper(WheelMapper.class); @Mapping(target = "color", expression = "java(getWheelColor(dto, wheelNumber))") @Mapping(target = "shape", expression = "java(getWheelShape(dto, wheelNumber))") WheelEntity dtoToWheel(BikeDTO dto, @Context Integer wheelNumber); // 根据轮号获取对应颜色字段 default String getWheelColor(BikeDTO dto, Integer wheelNumber) { return wheelNumber == 1 ? dto.getWheel_1_color() : dto.getWheel_2_color(); } // 根据轮号获取对应形状字段 default String getWheelShape(BikeDTO dto, Integer wheelNumber) { return wheelNumber == 1 ? dto.getWheel_1_shape() : dto.getWheel_2_shape(); } }
2. 修改BikeMapper,调用带参数的WheelMapper方法
在BikeMapper中,直接通过expression调用WheelMapper的映射方法,分别传递轮号1和2:
@Mapper public interface BikeMapper { BikeMapper INSTANCE = Mappers.getMapper(BikeMapper.class); @Mapping(target = "wheel1", expression = "java(WheelMapper.INSTANCE.dtoToWheel(dto, 1))") @Mapping(target = "wheel2", expression = "java(WheelMapper.INSTANCE.dtoToWheel(dto, 2))") BikeEntity dtoToEntity(BikeDTO dto); }
备选方案(贴近你最初的思路)
如果不想用expression,可以通过@Named区分两个轮的映射逻辑,内部统一调用带参数的WheelMapper方法:
@Mapper public interface BikeMapper { BikeMapper INSTANCE = Mappers.getMapper(BikeMapper.class); @Mapping(target = "wheel1", source = ".", qualifiedByName = "wheel1Mapper") @Mapping(target = "wheel2", source = ".", qualifiedByName = "wheel2Mapper") BikeEntity dtoToEntity(BikeDTO dto); @Named("wheel1Mapper") default WheelEntity mapWheel1(BikeDTO dto) { return WheelMapper.INSTANCE.dtoToWheel(dto, 1); } @Named("wheel2Mapper") default WheelEntity mapWheel2(BikeDTO dto) { return WheelMapper.INSTANCE.dtoToWheel(dto, 2); } }
说明
- 使用
@Context注解传递轮号参数,该参数仅作为上下文数据,不会被当作映射源处理。 - 通过默认方法实现动态字段获取,无需反射操作,保证类型安全。
- 两种方案都不需要修改DTO和实体结构,完全满足你的需求。
内容的提问来源于stack exchange,提问作者Gerald
相关产品推荐
相关产品推荐

