Mapstruct 简单对象之间映射(超详细)
一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
截止目前, 星球 内专栏累计输出 72w+ 字,讲解图 3103+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2400+ 小伙伴加入学习 ,欢迎点击围观
在项目中,我们经常会遇到需要把一个对象转换为另一个对象的需求,比如数据库对象转换成 DTO
(数据传输)对象。本小节中,小哈将演示如何使用 MapStruct 实现简单对象之间的映射。
1. 创建源对象和目标对象
首先,我们定义两个简单的 Java 对象:User
作为源对象和 UserDTO
作为目标对象。
源对象
public class User {
/**
* ID
*/
private Long id;
/**
* 用户名
*/
private String username;
/**
* 邮箱
*/
private String email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
'}';
}
}
目标对象
public class UserDTO {
/**
* ID
*/
private Long id;
/**
* 用户名
*/
private String username;
/**
* 邮箱
*/
private String email;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "UserDTO{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
'}';
}
}
注意:这里
User
和UserDTO
的字段名完全匹配的。
2. 定义映射接口
接下来,我们需要定义一个接口,MapStruct 会在编译时基于这个接口生成实际的映射类。
@Mapper
public interface UserConvert {
// 静态实例
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
UserDTO toUserDTO(User user);
User toUser(UserDTO userDTO);
}
这里,我们使用了 @Mapper
注解来声明这是一个 MapStruct 映射器,并定义了两个映射方法。
3. 实现映射
由于 MapStruct 在编译时会为我们自动生成映射的实现,所以我们实际上不需要手动写这些实现代码。我们只需要在需要的地方通过 UserMapper.INSTANCE
调用映射方法即可。
我们可以执行 mvn clean compile
命令,看看编译后的源文件,是否已经自动生成了映射相关的代码:
可以看到,Mapstruct 自动生成了 UserConvert
的实现类,相关映射方法也实现好了,终于不用手动 set
方法了。
4. 如何使用?
新建一个单元测试方法,使用方法如下:
@Test
public void testConvert() {
User user = new User();
user.setId(1L);
user.setEmail("quanxiaoha@qq.com");
user.setUsername("犬小哈");
UserDTO userDTO = UserConvert.INSTANCE.toUserDTO(user);
// 打印对象,看看是否映射成功
System.out.println(userDTO);
}
执行该单元测试,控制台输出如下:
可以看到字段都映射成功了。
5. 自定义字段映射
如果源对象和目标对象的字段名不完全匹配,MapStruct 提供了 @Mapping
注解来自定义字段之间的映射关系。
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
@Mapping(source = "username", target = "name")
@Mapping(source = "email", target = "emailAddress")
@Mapping(source = "id", target = "identifier")
UserDTO toUserDTO(User user);
@Mapping(source = "name", target = "username")
@Mapping(source = "emailAddress", target = "email")
@Mapping(source = "identifier", target = "id")
User toUser(UserDTO userDTO);
}
这里,source
是源对象的字段名,target
是目标对象的字段名。
6. 小结
MapStruct 为我们提供了一个简洁、高效的方式来实现对象之间的映射。它遵循“约定优于配置”的原则,对于大多数常见的映射场景,我们不需要写任何实现代码。当需要自定义映射时,MapStruct 也提供了灵活而强大的配置选项。