如何在MapStruct中实现两种集合更新策略:替换与追加?
MapStruct实现集合元素追加的更新方法
要实现向集合中追加元素的更新逻辑,而非默认的全量替换,可采用以下两种方案:
方案一:自定义默认方法手动处理
在ParentMapper接口中编写默认方法,先复用原有更新逻辑处理非集合字段,再手动实现子集合的追加:
@Mapper( componentModel = "spring", uses = {ChildMapper.class}) public interface ParentMapper { // 默认替换集合的更新方法(正常运行) Parent updateParent(ParentTo to, @MappingTarget Parent parent); // 追加子元素的更新方法 default Parent updateParentAddChild(ParentTo to, @MappingTarget Parent parent) { // 先更新name等非集合字段 updateParent(to, parent); // 处理子集合追加,避免空指针 if (to.getChildren() == null || to.getChildren().isEmpty()) { return parent; } if (parent.getChildren() == null) { parent.setChildren(new ArrayList<>()); } // 转换DTO并追加到原有集合 to.getChildren().forEach(childTo -> parent.getChildren().add(ChildMapper.INSTANCE.toChild(childTo)) ); return parent; } }
方案二:用@Named指定自定义集合映射策略
通过标记自定义的集合处理方法,让MapStruct在更新时调用该方法实现追加:
@Mapper( componentModel = "spring", uses = {ChildMapper.class}) public interface ParentMapper { // 默认替换集合的更新方法 Parent updateParent(ParentTo to, @MappingTarget Parent parent); // 标记自定义的集合追加逻辑 @Named("appendChildren") default void appendChildren(List<ChildTo> source, @MappingTarget List<Child> target, ChildMapper childMapper) { if (source == null || source.isEmpty()) { return; } if (target == null) { target = new ArrayList<>(); } source.forEach(childTo -> target.add(childMapper.toChild(childTo))); } // 指定children字段使用自定义的追加逻辑 @Mapping(target = "children", qualifiedByName = "appendChildren") Parent updateParentAddChild(ParentTo to, @MappingTarget Parent parent); }
关键注意点
- 确保
ChildMapper中存在Child toChild(ChildTo childTo)方法,用于完成DTO到实体的转换。 - 必须处理集合为null的情况,初始化空集合后再追加元素,防止空指针异常。
内容的提问来源于stack exchange,提问作者wuttke
相关产品推荐
相关产品推荐

