MapStruct能否按carId将不同类型集合映射为同一目标集合?
MapStruct实现多集合关联映射方案
MapStruct本身没有直接提供多集合按字段关联映射的原生注解,但可以通过先转Map再关联的方式实现你的需求,同时也给你讲清楚@IterableMapping的实际用法。
实现步骤与代码示例
先把两个Set转成以
carId为键的Map
用@MapMapping注解指定从对象的carId字段生成Map的key,自动完成集合到Map的转换:@Mapper public interface CarMapper { // 将Model集合转为key=carId的Map @MapMapping(keyTargetType = Long.class, keySource = "carId") Map<Long, Model> modelSetToMap(Set<Model> models); // 将Make集合转为key=carId的Map @MapMapping(keyTargetType = Long.class, keySource = "carId") Map<Long, Make> makeSetToMap(Set<Make> makes);编写默认方法完成关联映射
在Mapper里加一个default方法,利用上面的Map按carId匹配,调用你已有的from方法生成CarDto:default Set<CarDto> toCarDtoSet(Set<Model> models, Set<Make> makes) { Map<Long, Model> modelMap = modelSetToMap(models); Map<Long, Make> makeMap = makeSetToMap(makes); // 遍历其中一个Map,匹配carId生成CarDto,过滤掉无匹配项 return makeMap.entrySet().stream() .filter(entry -> modelMap.containsKey(entry.getKey())) .map(entry -> from(modelMap.get(entry.getKey()), entry.getValue())) .collect(Collectors.toSet()); } // 你已定义的单个映射方法 @Mapping(source = "model.name", target = "modelName") @Mapping(source = "make.name", target = "makeName") CarDto from(Model model, Make make); }
@IterableMapping的实际用法
这个注解只针对单集合的映射场景,用来配置集合转换的额外规则,比如指定用哪个命名的转换方法、日期格式化、空值处理等,不适合你当前多集合关联的需求。举个简单例子:
@Mapper public interface ModelMapper { // 用@IterableMapping指定使用命名为"modelToDto"的转换方法 @IterableMapping(qualifiedByName = "modelToDto") Set<ModelDto> modelSetToDtoSet(Set<Model> models); @Named("modelToDto") @Mapping(source = "name", target = "modelName") ModelDto modelToDto(Model model); }
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

