mapstruct-plus
- 一、基本介绍
- 二、快速集成
- 三、基本用法
- 四、进阶用法
- 五、手动自定义 Mapper
- 六、常见问题
- 1. 为什么 `converter.convert(...)` 报错说找不到转换器?
- 2. DTO ↔ Entity 字段名不一致,无法自动转换怎么办?
- 3. `List<VO>` 或 `Page<VO>` 转换失败?
- 4. 自动生成的 Mapper 类找不到?
- 5. 支持多对一或一对多嵌套对象映射吗?
- 6. 想要忽略某些字段怎么做?
- 7. 可以一个类映射多个目标类吗?
- 8. 兼容 Spring Boot 什么版本?
- 9. 如何调试或查看生成的 Mapper 代码?
- 10. Lombok 和 MapStruct 冲突怎么办?
- 11.NoSuchConverterException: Cannot find converter from UserDTO to UserVO
- io.github.linpeilie.ConvertException: cannot find converter from TerminalModel to TerminalModelVo
一、基本介绍
mapstruct-plus 是对 MapStruct 的增强封装,提供如下特性:
- 使用注解
@AutoMapper自动生成单向或双向映射; - 自动注册到 Spring 容器;
- 提供统一的
Converter工具类; - 支持集合、嵌套对象、泛型映射;
- 支持字段名不一致的映射;
二、快速集成
1. 添加依赖(Maven)
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
2. 启用注解处理器(IDEA)
- 设置路径:
File > Settings > Build, Execution, Deployment > Compiler > Annotation Processors - 勾选 ✅ “Enable annotation processing”
3.启用注解处理器
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-processor</artifactId>
<version>${mapstruct-plus.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
三、基本用法
1. 定义 DTO 和 VO
@Data
public class UserDTO {
private String username;
private Integer age;
}
@Data
@AutoMapper(target = UserDTO.class) // 自动生成双向映射
public class UserVO {
private String username;
private Integer age;
}
✅ 说明:此时会自动生成:
UserVO → UserDTOUserDTO → UserVO
2. 使用 Converter 工具类
@Autowired
private Converter converter;
// VO → DTO
UserDTO dto = converter.convert(vo, UserDTO.class);
// DTO → VO
UserVO vo = converter.convert(dto, UserVO.class);
Converter会在启动时收集所有@AutoMapper信息,并注册转换逻辑。
四、进阶用法
1. 关闭反向转换
@AutoMapper(target = UserDTO.class, reverseConvertGenerate = false)
public class UserVO { ... }
此时只能执行 VO → DTO,不能 DTO → VO。
2. 多目标映射
@AutoMappers({
@AutoMapper(target = User2.class),
@AutoMapper(target = User1.class),
})
public class UserVO { ... }
支持将 VO 同时映射到 DTO 和实体。
3. 自定义字段映射(字段名不同)
使用 @AutoMappings + @AutoMapping:
@Data
@AutoMapper(target = UserDTO.class)
@AutoMappings({
@AutoMapping(source = "name", target = "username"),
@AutoMapping(source = "birth", target = "age", expression = "java(calculateAge(vo.getBirth()))")
})
public class UserVO {
private String name;
private LocalDate birth;
}
也可自定义 Mapper 接口。
4. 支持集合和分页对象
List<UserDTO> dtoList = converter.convert(voList, UserDTO.class);
Page<UserDTO> dtoPage = converter.convert(voPage, UserDTO.class);
支持 Spring Data、MyBatis Plus 等常见分页对象(自动封装)。
五、手动自定义 Mapper
@Mapper(componentModel = "spring")
public interface CustomMapper {
UserDTO toDTO(UserVO vo);
UserVO toVO(UserDTO dto);
}
然后注入使用:
@Autowired
private CustomMapper customMapper;
这种方式适合需要复杂逻辑或多个类组合映射时使用。
六、常见问题
1. 为什么 converter.convert(...) 报错说找不到转换器?
-
原因:
- 你的类没有加
@AutoMapper - 没开启 IDEA 的注解处理器
reverseConvertGenerate = false,却调用了反向转换- 没有正确引入
mapstruct-plus-spring-boot-starter
- 你的类没有加
-
解决方案:
- 在 DTO、VO、Entity 中至少有一个类加上
@AutoMapper(target = Xxx.class) - 确保 IDEA 设置中 Enable annotation processing 打开
- 检查 pom 中是否引入了
mapstruct-plus-spring-boot-starter - 检查生成的代码是否存在于
target/generated-sources/annotations目录下- clean项目,rebuild project,再试
- 在 DTO、VO、Entity 中至少有一个类加上
2. DTO ↔ Entity 字段名不一致,无法自动转换怎么办?
解决方案:
加上字段映射规则:
@AutoMappings({
@AutoMapping(source = "name", target = "username")
})
@AutoMapper(target = UserDTO.class)
public class UserVO {
private String name;
}
或使用 MapStruct 标准的 @Mapping 注解时自定义 Mapper 接口。
3. List<VO> 或 Page<VO> 转换失败?
解决方案:
-
确保单个对象的转换关系存在(VO ↔ DTO 已配置)
-
使用
converter.convert(list, TargetClass.class),框架会识别集合类型 -
Page仅支持常见分页实现,如:org.springframework.data.domain.Pagecom.baomidou.mybatisplus.extension.plugins.pagination.Page
4. 自动生成的 Mapper 类找不到?
解决方案:
- 看看
target/generated-sources/annotations目录是否存在生成的XxxMapperImpl - IDEA 中没有索引这个目录时,
Rebuild Project一下 - 检查是否设置了 module 编译输出路径
5. 支持多对一或一对多嵌套对象映射吗?
是的,支持嵌套对象、集合、泛型对象映射:
@AutoMapper(target = OrderDTO.class)
public class OrderVO {
private List<OrderItemVO> items;
}
只要 OrderItemVO ↔ OrderItemDTO 的映射也存在,它会递归地完成嵌套映射。
6. 想要忽略某些字段怎么做?
使用 @AutoMapping(ignore = true) 或自定义 Mapper:
@AutoMappings({
@AutoMapping(target = "password", ignore = true)
})
@AutoMapper(target = UserDTO.class)
public class UserVO {
private String username;
private String password; // 不希望传出去
}
7. 可以一个类映射多个目标类吗?
可以。一个类上可加多个 @AutoMapper 注解:
@AutoMapper(target = UserDTO.class)
@AutoMapper(target = UserEntity.class)
public class UserVO { ... }
注意:多个
target时,生成的转换器名字会带有目标类名。
8. 兼容 Spring Boot 什么版本?
mapstruct-plus 没有强依赖 Spring Boot 版本,通常兼容:
- Spring Boot 2.3 ~ 3.x
- Spring Framework 5.x ~ 6.x
你可以在 spring.factories 中看到它通过自动配置方式启用。
9. 如何调试或查看生成的 Mapper 代码?
在 target/generated-sources/annotations/ 目录下,可以查看 XxxMapperImpl.java 文件,里面就是 MapStruct 实际生成的代码。
10. Lombok 和 MapStruct 冲突怎么办?
Lombok 与 MapStruct 并不冲突,但建议始终:
- 开启注解处理器(两者都依赖)
- 保证 Lombok、MapStruct、mapstruct-plus 的版本兼容
- 避免在映射对象中使用 Lombok 的
@Builder(除非你知道它会影响构造器)
11.NoSuchConverterException: Cannot find converter from UserDTO to UserVO
两个类都没有标注 @AutoMapper,就等于你没有告诉框架要为这两个类生成映射关系,就会报这个
io.github.linpeilie.ConvertException: cannot find converter from TerminalModel to TerminalModelVo
字段名错误,字段名写成了user_name,但是使用mybatisplus查询结果是驼峰的,没法映射给user_name。

4130

被折叠的 条评论
为什么被折叠?



