springboot maven项目 集成org.mapstruct.Mapper
java运行// 源对象:UserDO(数据库实体)@Data // Lombok 注解// 字段名不一致示例// 目标对象:UserVO(前端展示)@Data// 对应 id// 对应 userName// 格式化后的创建时间通过@Mapper注解声明映射接口,指定让 Spring 管理 Bean:java运行/*** 映射接口* componentModel = "spring":生成的实现类
在 Spring Boot Maven 项目中集成 MapStruct(对象映射工具)可大幅简化对象之间的属性拷贝,以下是完整的集成步骤 + 核心示例 + 避坑指南:
一、核心依赖(pom.xml)
MapStruct 核心依赖分为两部分:API 包(编译 / 运行时) + 注解处理器(编译时生成映射实现类),需结合 Lombok(若使用)适配版本。
1. 基础依赖(无 Lombok)
xml
<dependencies>
<!-- MapStruct 核心 API -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version> <!-- 稳定版,推荐使用 -->
</dependency>
<!-- Spring Boot 基础依赖(按需) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven 编译插件(必须配置注解处理器) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>1.8</source> <!-- 适配你的 JDK 版本(8/11/17) -->
<target>1.8</target>
<annotationProcessorPaths>
<!-- MapStruct 注解处理器 -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2. 适配 Lombok(常用场景)
若项目使用 Lombok,需在 annotationProcessorPaths 中添加 Lombok 处理器,且注意版本兼容:
xml
<dependencies>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 其他依赖(MapStruct + Spring Boot)同上 -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<!-- MapStruct 处理器(必须放第一个) -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
<!-- Lombok 处理器 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 适配你的 Lombok 版本 -->
</path>
<!-- 若使用 Lombok 1.18.16+,需添加此处理器(解决兼容问题) -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
二、核心使用示例
1. 定义源对象和目标对象
java
运行
// 源对象:UserDO(数据库实体)
@Data // Lombok 注解
public class UserDO {
private Long id;
private String userName; // 字段名不一致示例
private Integer age;
private LocalDateTime createTime;
}
// 目标对象:UserVO(前端展示)
@Data
public class UserVO {
private Long userId; // 对应 id
private String name; // 对应 userName
private Integer age;
private String createTimeStr; // 格式化后的创建时间
}
2. 定义 MapStruct 映射接口
通过 @Mapper 注解声明映射接口,指定 componentModel = "spring" 让 Spring 管理 Bean:
java
运行
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 映射接口
* componentModel = "spring":生成的实现类会被 Spring 扫描为 Bean
*/
@Mapper(componentModel = "spring")
public interface UserMapper {
// 字段映射规则
@Mapping(source = "id", target = "userId") // 字段名不一致
@Mapping(source = "userName", target = "name")
@Mapping(source = "createTime", target = "createTimeStr",
qualifiedByName = "formatCreateTime") // 自定义转换方法
UserVO doToVo(UserDO userDO);
// 自定义字段转换方法(@Named 标记)
@Named("formatCreateTime")
default String formatCreateTime(LocalDateTime createTime) {
if (createTime == null) {
return null;
}
return createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}
3. 业务层使用映射接口
直接注入 UserMapper 即可使用:
java
运行
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public UserVO getUserInfo() {
// 模拟数据库查询
UserDO userDO = new UserDO();
userDO.setId(1L);
userDO.setUserName("张三");
userDO.setAge(20);
userDO.setCreateTime(LocalDateTime.now());
// 转换为 VO
return userMapper.doToVo(userDO);
}
}
4. 测试验证
编写测试类验证转换结果:
java
运行
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class UserMapperTest {
@Resource
private UserMapper userMapper;
@Test
public void testDoToVo() {
UserDO userDO = new UserDO();
userDO.setId(1L);
userDO.setUserName("张三");
userDO.setAge(20);
userDO.setCreateTime(LocalDateTime.of(2025, 12, 26, 10, 0, 0));
UserVO userVO = userMapper.doToVo(userDO);
System.out.println(userVO);
// 输出:UserVO(userId=1, name=张三, age=20,
createTimeStr=2025-12-26 10:00:00)
}
}
三、关键配置说明
| 配置项 | 作用 |
|---|---|
componentModel |
生成的实现类的组件模型:- spring:Spring Bean(推荐)- default:手动通过 Mappers.getMapper() 获取- cdi:CDI 容器管理- jsr330:JSR330 注解(@Inject) |
@Mapping |
单个字段映射规则:- source:源字段名- target:目标字段名- ignore:是否忽略(ignore = true)- qualifiedByName:指定自定义转换方法- dateFormat:日期格式化(如 dateFormat = "yyyy-MM-dd") |
@Mapper 注解 |
标记映射接口,uses 属性可引入其他映射器(如 uses = OrderMapper.class) |
四、常见问题与避坑
-
编译后未生成实现类
- 原因:注解处理器未配置或版本不兼容。
- 解决:确保
maven-compiler-plugin中配置了mapstruct-processor,且版本与mapstruct核心包一致。
-
Lombok + MapStruct 字段未映射
- 原因:注解处理器顺序问题(Lombok 需在 MapStruct 之后)。
- 解决:在
annotationProcessorPaths中,mapstruct-processor放第一个,lombok放后面,且添加lombok-mapstruct-binding。
-
Spring 注入失败(No qualifying bean)
- 原因:
componentModel未设为spring,或编译未生成实现类。 - 解决:
@Mapper(componentModel = "spring"),并执行mvn clean compile重新编译。
- 原因:
五、高级用法(可选)
- 集合映射:直接定义 List 转换方法,MapStruct 自动生成循环转换逻辑:
java
运行
List<UserVO> doListToVoList(List<UserDO> userDOList); - 多源对象映射:合并多个对象到一个目标对象:
java
运行
@Mapping(source = "userDO.id", target = "userId") @Mapping(source = "orderDO.orderNo", target = "orderNumber") UserDetailVO merge(UserDO userDO, OrderDO orderDO); - 默认值与空值处理:
java
运行
@Mapping(source = "age", target = "age", defaultValue = "0") // 源字段为 null 时设默认值 @Mapping(source = "name", target = "name", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL) // 空值策略
总结
集成 MapStruct 的核心是:
- 引入正确的依赖(API + 注解处理器);
- 配置 Maven 编译插件指定注解处理器;
- 定义
@Mapper接口并配置映射规则; - Spring 环境下指定
componentModel = "spring"实现依赖注入。
MapStruct 相比 BeanUtils 优势:编译时生成实现类(性能更高)、支持自定义转换逻辑、类型安全(编译期校验),是 Spring Boot 项目中对象映射的首选方案。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)