在 Java 开发中,DTO(Data Transfer Object)与实体类之间的转换通常是一个频繁的任务,尤其在构建复杂的应用时。手动进行转换不仅繁琐,还容易出错。为了提高开发效率并减少转换代码的冗余,我们可以使用 MapStruct —— 一个基于注解的 Java 对象映射框架,它能在编译时生成类型安全、性能优越的代码。
在这篇博客中,我将向大家展示如何在 Spring Boot 项目中整合 MapStruct,并通过具体示例介绍如何使用它进行对象的转换。
你可以通过 Spring Initializr 生成一个基本的 Spring Boot 项目,选择以下依赖:
如果你已经创建了项目,接下来需要在 pom.xml
中添加 MapStruct 相关依赖。
xml<dependencies>
<!-- MapStruct 核心库 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<!-- MapStruct 处理器 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
<scope>provided</scope>
</dependency>
<!-- Lombok (可选,用于减少样板代码) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
</dependencies>
为了确保 MapStruct 编译时生成代码,需要配置插件:
xml<build>
<plugins>
<!-- 配置 Maven 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
首先,我们定义一个简单的 User
实体类,代表数据库中的用户信息。
java@Data
public class User {
private Long id;
private String username;
private String email;
private String date;
}
接着创建一个与实体类相对应的 DTO 类,用于传输用户数据。
java@Data
public class UserDTO {
private String username;
private String email;
private LocalDate date;
}
使用 MapStruct 的核心是定义一个 @Mapper
接口。MapStruct 将会在编译时生成这个接口的实现类,接口中定义的默认default
方法,在对象拷贝时,框架会自动根据参数和返回值自动调用。
javaimport org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDTO userToUserDTO(User user);
User userDTOToUser(UserDTO userDTO);
/**
* 自定义属性名称相同类型不同的属性转换规则
* 格式化字符串——》日期
*/
default LocalDate mapStringToLocalDate(String value) {
return LocalDate.parse(value);
}
/**
* 自定义属性名称相同类型不同的属性转换规则
* 日期——》格式化字符串
*/
default LocalDate mapLocalDateToString(LocalDate value) {
return value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
}
在上面的代码中,UserMapper
是一个接口,我们使用 @Mapper
注解来标记它。MapStruct 将自动生成实现这个接口的类。
在编写完 Mapper 接口后,我们可以测试对象转换是否正确。
javapublic class UserMapperTest {
public static void main(String[] args) {
// 创建 User 实例
User user = new User();
user.setId(1L);
user.setUsername("JohnDoe");
user.setEmail("john.doe@example.com");
// 使用 MapStruct 进行转换
UserDTO userDTO = UserMapper.INSTANCE.userToUserDTO(user);
System.out.println("UserDTO: " + userDTO);
}
}
输出结果:
plaintextUserDTO: UserDTO(username=JohnDoe, email=john.doe@example.com)
这样,我们就完成了实体到 DTO 的转换。
为了在 Spring Boot 项目中整合 MapStruct 并使其与 Spring 的依赖注入机制一起工作,我们需要在 @Mapper
注解中添加 componentModel = "spring"
配置。这样 MapStruct 生成的实现类将会成为 Spring 的 Bean
,可以通过 @Autowired
注入。
java@Mapper(componentModel = "spring")
public interface UserMapper {
UserDTO userToUserDTO(User user);
User userDTOToUser(UserDTO userDTO);
}
现在我们可以在 Spring Boot 项目中通过依赖注入使用 MapStruct。
javaimport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final UserMapper userMapper;
public UserController(UserMapper userMapper) {
this.userMapper = userMapper;
}
@GetMapping("/user")
public UserDTO getUser() {
// 模拟从数据库获取用户
User user = new User();
user.setId(1L);
user.setUsername("JohnDoe");
user.setEmail("john.doe@example.com");
// 使用 MapStruct 转换为 DTO
return userMapper.userToUserDTO(user);
}
}
启动 Spring Boot 项目,访问 http://localhost:8080/user
,将会返回一个 UserDTO
的 JSON 对象:
json{
"username": "JohnDoe",
"email": "john.doe@example.com"
}
如果字段名不同,可以使用 @Mapping
注解自定义字段的映射。例如:
java@Mapper(componentModel = "spring")
public interface UserMapper {
@Mapping(source = "email", target = "emailAddress")
UserDTO userToUserDTO(User user);
}
MapStruct 还支持将集合进行映射:
javaList<UserDTO> userToUserDTOList(List<User> users);
通过 MapStruct,我们能够非常方便、快捷地实现对象之间的转换,极大减少了手写转换代码的繁琐。与 Spring Boot 整合后,通过依赖注入的方式,可以让转换逻辑更加简洁清晰。
MapStruct 是处理对象映射的强大工具,适用于各种复杂项目中数据传输对象与实体对象的转换需求。
希望这篇文章能帮助大家更好地理解和使用 Spring Boot 与 MapStruct 的整合。如果你有任何疑问或建议,欢迎评论交流!