如何为MapStruct生成的list.add加条件?注解或映射返回null可行吗?
MapStruct 集合转换加条件 & 控制toDto返回null的问题
一、给集合转换的list.add加条件(不用重写toDto)
MapStruct提供了@Condition注解专门做集合元素过滤,比重写toDto简便很多,步骤如下:
- 在你的Mapper接口里定义一个条件判断方法,用
@Condition标记:
@Condition boolean isValidStudentMenu(StudentMenu studentMenu) { // 这里写你的过滤规则,比如判断状态有效、id不为空等 return studentMenu != null && studentMenu.getStatus() == 1; }
- 在集合转换方法上用
@IterableMapping关联这个条件:
@IterableMapping(condition = "isValidStudentMenu") List<StudentMenuDto> toDtoList(List<StudentMenu> studentMenus);
生成的StudentMenuMapperImpl中,循环处理集合时会先调用isValidStudentMenu判断,只有符合条件的元素才会执行toDto并添加到结果列表里,完全不用重写整个toDto方法。
二、用@AfterMapping/@BeforeMapping能不能让toDto返回null?
不行。@BeforeMapping和@AfterMapping只是转换前后的逻辑钩子,只能执行额外操作,没办法修改toDto方法的返回值,也不能让方法直接返回null。
如果要实现toDto根据条件返回null,推荐两种直接的方式:
方式1:用默认方法封装转换逻辑
在Mapper接口里写一个带条件判断的默认方法,内部调用MapStruct生成的实际转换方法:
@Nullable default StudentMenuDto toDto(StudentMenu studentMenu) { // 这里写你的判断条件 if (studentMenu == null || studentMenu.isDeleted()) { return null; } // 调用MapStruct生成的内部转换方法 return toDtoInternal(studentMenu); } // 让MapStruct生成这个内部转换方法,配置字段映射规则 @Mapping(target = "menuName", source = "name") StudentMenuDto toDtoInternal(StudentMenu studentMenu);
方式2:用@ObjectFactory(进阶场景)
如果需要更灵活的对象创建控制,可以用@ObjectFactory注解在创建DTO对象前做判断,但大多数场景下默认方法已经足够用了。
总结:集合过滤用@Condition+@IterableMapping是最简便的方案;控制toDto返回null无法依赖@Before/@AfterMapping,用默认方法封装转换逻辑最直接。
内容的提问来源于stack exchange,提问作者Jun
相关产品推荐
相关产品推荐

