MapStruct简介
MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach.
The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand.
—— 引自MapStruct官网
MapStruct是一个开源的代码生成器,极大地简化了从一种Java对象到另一种Java对象的转换过程。
MapStruct常用注解
注解 | 说明 |
---|---|
@Mapper |
用于标注Mapper接口,MapStruct根据接口定义自动生成Mapper实现类。 |
@Mapping |
用于标注接口方法或者参数,指示源属性与目标属性之间的映射关系。可以通过source 和target 属性指定源和目标属性的名称。 |
@Mappings |
用于标注多个@Mapping 注解,方便在一个接口方法中定义多个属性的映射关系。 |
@Mapper
注解常用属性:
-
componentModel
属性:默认值为default
。在Spring项目中通过自动注入的方式使用MapStruct Mapper类,需要将componentModel
属性的属性值改为spring
。 -
unmappedTargetPolicy
属性:指定目标对象中未映射属性的处理策略。默认为IGNORE
,表示忽略未映射的属性。其他可选值包括WARN
、ERROR
和REPORT
。
集成MapStruct
添加MapStruct依赖
修改pom.xml
文件,添加如下代码:
...
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.24</lombok.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
说明:
-
mapstruct-processor
:MapStruct注解处理器。
入门示例:属性完全相同
1、创建一个实体类 —— User.java
package cn.ddcherry.springboot.demo.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private String id;
private String usercode;
private String name;
}
2、创建一个DTO类 —— UserDto.java
package cn.ddcherry.springboot.demo.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class UserDto {
private String id;
private String usercode;
private String name;
}
说明:
实体类和DTO类的属性(类型、名称)完全相同。
3、创建一个转换器类 —— UserMapper.java
package cn.ddcherry.springboot.demo.mapper;
import cn.ddcherry.springboot.demo.dto.UserDto;
import cn.ddcherry.springboot.demo.entity.User;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDto toDto(User entity);
User toEntity(UserDto dto);
List<UserDto> toDto(List<User> entityList);
List<User> toEntity(List<UserDto> dtoList);
}
4、创建一个测试类 —— UserMapperTest.java
package cn.ddcherry.springboot.demo;
import cn.ddcherry.springboot.demo.dto.UserDto;
import cn.ddcherry.springboot.demo.entity.User;
import cn.ddcherry.springboot.demo.mapper.UserMapper;
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 testEntityToDto() {
User user = new User("001", "user-001", "嗨皮汪小成");
UserDto dto = userMapper.toDto(user);
System.out.println(dto);
}
}
输出结果:
UserDto(id=001, usercode=user-001, name=嗨皮汪小成)
程序运行成功后,我们可以在IDEA中打开target目录下的class文件,看一下MapStruct自动生成的转换器实现。笔者汪小成截取了toDto(...)
和toDtoList(...)
两个方法的实现,如下图:
简单封装
在Spring Boot项目中,我们可以将Entity与DTO间转换的方法提取到一个基础转换器中,其它所有需要进行Entity与DTO转换的类都继承这个类。
基础转换器类 —— BaseMapper.java
package cn.ddcherry.springboot.demo.mapper;
import java.util.List;
public interface BaseMapper<D, E> {
D toDto(E entity);
E toEntity(D dto);
List<D> toDto(List<E> entityList);
List<E> toEntity(List<D> dtoList);
}
一个具体转换器类 —— UserMapper.java
package cn.ddcherry.springboot.demo.mapper;
import cn.ddcherry.springboot.demo.dto.UserDto;
import cn.ddcherry.springboot.demo.entity.User;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper extends BaseMapper<UserDto, User> {
}
## Spring Boot系列文章
- [Spring Boot | 手动创建多模块项目](https://blog.51cto.com/u_15870409/6096056)
- [Spring Boot | 手动创建一个简单的Spring Boot项目](https://blog.51cto.com/ddcherry/6098485)
- [Spring Boot | 集成Thymeleaf模板引擎](https://blog.51cto.com/ddcherry/6100030)
- [Spring Boot | 整合Swagger、Knife4j自动生成API文档](https://blog.51cto.com/u_15870409/6093957)