如何用MapStruct将多组XML Record映射到同一个FilteredDE实例?
MapStruct 实现多Record节点合并到单个实例的方案
核心思路
MapStruct 默认会为每个映射方法创建新的目标实例,要实现复用同一个目标实例填充所有属性,需要利用 MapStruct 的更新映射能力,结合自定义流程串联多个Record的映射逻辑。
具体实现步骤
1. 定义映射器接口,包含初始化与更新方法
创建映射器时,同时定义两个核心方法:
- 从单个Record生成初始FilteredDE实例
- 接收已存在的FilteredDE实例,用Record的属性更新它
@Mapper public interface FilteredDEMapper { // 初始化:从单个Record生成FilteredDE实例 FilteredDE recordToFilteredDE(Record record); // 更新:将Record的属性合并到已有FilteredDE实例 @Mapping(target = "id", ignore = true) // 示例:忽略无需更新的属性 void updateFilteredDEFromRecord(Record record, @MappingTarget FilteredDE target); }
2. 业务代码中串联映射流程
先通过初始化方法创建第一个FilteredDE实例,再遍历所有group下的Record,逐个调用更新方法完成全属性填充:
// 假设已通过JAXB解析得到List<Group> groups FilteredDEMapper mapper = Mappers.getMapper(FilteredDEMapper.class); FilteredDE result = null; for (Group group : groups) { for (Record record : group.getRecords()) { if (result == null) { // 第一次初始化实例 result = mapper.recordToFilteredDE(record); } else { // 复用已有实例,填充新属性 mapper.updateFilteredDEFromRecord(record, result); } } }
3. 关键配置说明
@MappingTarget注解:标记目标实例参数,MapStruct会生成代码将源对象属性赋值给该实例,而非创建新对象- 忽略特定属性:如果某些属性仅需初始化时设置,后续更新不需要覆盖,可通过
@Mapping(target = "xxx", ignore = true)配置 - 空值自动跳过:MapStruct默认会跳过源对象中为null的属性(JAXB生成的Record中不存在的属性即为null),刚好符合只填充XML中存在属性的需求
4. 进阶:封装批量处理方法
可在映射器中添加默认方法简化批量处理逻辑:
@Mapper public interface FilteredDEMapper { FilteredDE recordToFilteredDE(Record record); @Mapping(target = "id", ignore = true) void updateFilteredDEFromRecord(Record record, @MappingTarget FilteredDE target); // 批量合并所有Record到单个FilteredDE实例 default FilteredDE mergeRecordsToFilteredDE(List<Record> allRecords) { if (allRecords == null || allRecords.isEmpty()) { return null; } FilteredDE result = recordToFilteredDE(allRecords.get(0)); for (int i = 1; i < allRecords.size(); i++) { updateFilteredDEFromRecord(allRecords.get(i), result); } return result; } }
业务代码调用示例:
List<Record> allRecords = groups.stream() .flatMap(group -> group.getRecords().stream()) .collect(Collectors.toList()); FilteredDE result = mapper.mergeRecordsToFilteredDE(allRecords);
内容的提问来源于stack exchange,提问作者Viktor
相关产品推荐
相关产品推荐

