一、什麼是mapstruct
MapStruct是一個代碼生成器的工具類,簡化了不同的Java Bean之間映射的處理,所以映射指的就是從一個實體變化成一個實體。在實際項目中,我們經常會將PO轉DTO、DTO轉PO等一些實體間的轉換。在轉換時大部分屬性都是相同的,只有少部分的不同,這時我們可以通過mapStruct的一些註解來匹配不同屬性,可以讓不同實體之間的轉換變的簡單。
MapStruct官網地址: http://mapstruct.org/
二、添加依賴
<!--MapStruct依賴-->
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-jdk8 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.0.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.0.0.Final</version>
</dependency>
三、mapstruct實體間的轉換
//Info.java
public class Info{
private Integer userId;
private String email;
private Integer score;
private String remark;
//constructor, getters, setters etc.
}
//InfoDto.java
public class InfoDto{
private Integer id;
private Integer value;
private String remark;
private User user;
//constructor, getters, setters etc.
}
//User.java
public class User{
private Integer userId;
private String email;
//constructor, getters, setters etc.
}
四、mapper接口
要生成一個PeopleDTO與PeopleEntity對象相互轉換的映射器,我們需要定義一個mapper接口。像這兩個實體類有些屬性不一樣時,我們可以通過@Mapping註解來進行轉換.
- @Mapper註解標記這個接口作爲一個映射接口,並且是編譯時MapStruct處理器的入口。
- @Mapping解決源對象和目標對象中,屬性名字不同的情況。
- Mappers.getMapper自動生成的接口的實現可以通過Mapper的class對象獲取,從而讓客戶端可以訪問Mapper接口的實現。
@Mapper
public interface InfoMapper {
PeopleMapper INSTANCE = Mappers.getMapper(InfoMapper.class);
/**
* PO轉DTO
*
* @param info PO
* @return DTO
*/
@Mapping(target = "value", source = "score")
@Mapping(target = "user.userId", source = "userId")
@Mapping(target = "user.email", source = "email")
InfoDTO entityToDTO(Info info);
/**
* DTO轉PO
*
* @param infoDTO DTO
* @param entity PO
*/
@Mapping(target = "score", source = "value")
@Mapping(target = "userId", source = "user.userId")
@Mapping(target = "email", source = "user.email")
void updateInfoFromDto(InfoDTO InfoDTO, @MappingTarget Info info);
}
當運行是將會自動編譯我們的InfoMapper.java
下面是我在學習時寫的Mapper文件以及編譯後的一個文件
@Mapper(componentModel = "spring")
public interface TeamMapper {
TeamVo poToTeamVo(TeamPo teamPo);
Team poToTeamDo(TeamPo teamPo);
List<TeamVo> poListToVoList(List<TeamPo> teamPoList);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2019-08-08T13:30:54+0800",
comments = "version: 1.0.0.Final, compiler: javac, environment: Java 1.8.0_211 (Oracle Corporation)"
)
@Component
public class TeamMapperImpl implements TeamMapper {
@Override
public TeamVo poToTeamVo(TeamPo teamPo) {
if ( teamPo == null ) {
return null;
}
TeamVo teamVo = new TeamVo();
teamVo.setId( teamPo.getId() );
teamVo.setName( teamPo.getName() );
teamVo.setDepartmentId( teamPo.getDepartmentId() );
teamVo.setDepartmentName( teamPo.getDepartmentName() );
return teamVo;
}
@Override
public Team poToTeamDo(TeamPo teamPo) {
if ( teamPo == null ) {
return null;
}
Team team = new Team();
team.setId( teamPo.getId() );
team.setName( teamPo.getName() );
team.setDepartmentId( teamPo.getDepartmentId() );
return team;
}
@Override
public List<TeamVo> poListToVoList(List<TeamPo> teamPoList) {
if ( teamPoList == null ) {
return null;
}
List<TeamVo> list = new ArrayList<TeamVo>();
for ( TeamPo teamPo : teamPoList ) {
list.add( poToTeamVo( teamPo ) );
}
return list;
}
}
五、注意
1、 由於編譯可能不及時的原因,所以一開始遇到了修改了po或者dto的一個類,但是mapper沒有及時的重新編譯,所以dto,po,vo有更改的話,建議先clean一下之後重新編譯然後運行
2、 在使用mapstruct + lombok時要注意maven-comiler-plugin插件版本一定要在3.6.0以上,若版本低,則會報找不到屬性的錯誤
下面是一個依賴模板
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>xyz.suiwo</groupId>
<artifactId>gradingdog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gradingdog</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.2.0.Beta2</org.mapstruct.version>
<org.projectlombok.version>1.16.14</org.projectlombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!--MapStruct依賴-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>${java.version}</source> <!-- or higher, depending on your project -->
<target>${java.version}</target> <!-- or higher, depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>