如何用MapStruct将List元素映射到目标对象的指定属性?
用MapStruct实现列表元素到目标对象固定属性的映射
这个需求完全可以通过MapStruct实现,你之前尝试的source2List[0].field1写法失败,是因为MapStruct不支持直接在@Mapping的source属性中使用数组/列表下标进行嵌套属性访问。下面提供两种可行的实现方案:
方案一:使用@Mapping结合Java表达式
直接通过expression属性编写Java逻辑,处理列表的非空判断和元素提取,不存在的元素自动映射为null:
@Mapper(componentModel = "spring") // 根据项目环境选择,如spring、cdi等 public interface YourMapper { @Mapping(target = "status1", expression = "java(source2List != null && source2List.size() > 0 ? source2List.get(0).getField1() : null)") @Mapping(target = "code1", expression = "java(source2List != null && source2List.size() > 0 ? source2List.get(0).getField2() : null)") @Mapping(target = "status2", expression = "java(source2List != null && source2List.size() > 1 ? source2List.get(1).getField1() : null)") @Mapping(target = "code2", expression = "java(source2List != null && source2List.size() > 1 ? source2List.get(1).getField2() : null)") @Mapping(target = "status3", expression = "java(source2List != null && source2List.size() > 2 ? source2List.get(2).getField1() : null)") @Mapping(target = "code3", expression = "java(source2List != null && source2List.size() > 2 ? source2List.get(2).getField2() : null)") // 此处添加SourceObject1到TargetObject其他属性的映射规则 TargetObject mapSourcesToTarget(SourceObject1 source1, List<SourceObject2> source2List); }
方案二:自定义默认方法(Default Method)
如果觉得表达式写法不够优雅,可在Mapper接口中定义默认方法,先完成基础映射再手动处理列表元素赋值:
@Mapper(componentModel = "spring") public interface YourMapper { // 定义基础映射:仅处理SourceObject1到TargetObject的属性,忽略列表相关属性 @Mapping(target = "status1", ignore = true) @Mapping(target = "code1", ignore = true) @Mapping(target = "status2", ignore = true) @Mapping(target = "code2", ignore = true) @Mapping(target = "status3", ignore = true) @Mapping(target = "code3", ignore = true) TargetObject mapSource1ToTarget(SourceObject1 source1); // 自定义默认方法:整合source1和source2List的映射逻辑 default TargetObject mapSourcesToTarget(SourceObject1 source1, List<SourceObject2> source2List) { TargetObject target = mapSource1ToTarget(source1); if (source2List != null) { if (source2List.size() > 0) { target.setStatus1(source2List.get(0).getField1()); target.setCode1(source2List.get(0).getField2()); } if (source2List.size() > 1) { target.setStatus2(source2List.get(1).getField1()); target.setCode2(source2List.get(1).getField2()); } if (source2List.size() > 2) { target.setStatus3(source2List.get(2).getField1()); target.setCode3(source2List.get(2).getField2()); } } // 未匹配到的元素对应属性保持null,符合需求 return target; } }
注意事项
- 确保
SourceObject2类中存在对应的getField1()、getField2()getter方法,MapStruct依赖这些方法访问属性 - 根据项目依赖的DI框架选择合适的
componentModel,比如Spring项目用spring,可直接通过@Autowired注入Mapper实例 - 当
source2List为null或元素数量不足时,TargetObject中对应的属性会自动为null,完全符合需求
内容的提问来源于stack exchange,提问作者user9150507
相关产品推荐
相关产品推荐

