1 序
MapStruct
是一個屬性映射工具糟秘,只需要使用@Mapper
注解標(biāo)注的映射接口富俄。MapStruct
就會自動生成實現(xiàn)這個映射接口的實現(xiàn)類旦签,避免了復(fù)雜繁瑣的映射實現(xiàn)。MapStruct
官網(wǎng)地址: http://mapstruct.org/吮炕。
2 準(zhǔn)備工作
2.1 定義映射示例Bean
- 定義Mode Bean
package com.eugeneheen.mapstruct.api.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserModel {
private Long id;
private String name;
private String phone;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime createTm;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime updateTm;
}
- 定義Do Bean
package com.eugeneheen.mapstruct.dao.dataobject;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity(name = "t_user")
public class UserDo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private String phone;
@Column(name = "create_tm")
LocalDateTime createTm;
@Column(name = "update_tm")
LocalDateTime updateTm;
}
2.2 示例使用的相關(guān)依賴
- Lombok
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<optional>true</optional>
</dependency>
- MapStruct官方依賴
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct.extensions.spring</groupId>
<artifactId>mapstruct-spring-annotations</artifactId>
<version>0.1.0</version>
</dependency>
- MapStruct第三方依賴
<dependency>
<groupId>io.github.zhaord</groupId>
<artifactId>mapstruct-spring-plus-boot-starter</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
3 示例
3.1 關(guān)于依賴
3.1.1 Maven
-
SpringBoot
單模塊項目:直接在POM
文件加入相關(guān)依賴即可。 -
SpringBoot
多模塊項目-
打包
的模塊访得,POM
文件加入以下依賴:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.1</version> <configuration> <mainClass>com.eugeneheen.mapstruct.MapStructApplication</mainClass> <skip>false</skip> <layers> <enabled>true</enabled> </layers> <excludes> <!-- 打包的時候忽略lombok龙亲,解決生成了maptruct的實現(xiàn)類陕凹,但該類只創(chuàng)建了對象,沒有進行賦值 --> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
- 定義
映射接口
的模塊鳄炉,POM
文件加入以下依賴:<dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.4.2.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.4.2.Final</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <annotationProcessorPaths> <!-- 此處杜耙,lombok依賴一定要放在,Mapstruct-processor依賴之前拂盯。否則佑女,生成了maptruct的實現(xiàn)類,但該類只創(chuàng)建了對象谈竿,沒有進行賦值 --> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </path> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.4.2.Final</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
-
3.1.2 Gradle
- version >= 4.6
dependencies {
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
- version < 4.6
plugins {
id 'net.ltgt.apt' version '0.21'
}
dependencies {
compile 'org.mapstruct:mapstruct:1.4.2.Final'
apt 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
3.2 基礎(chǔ)使用示例
- 定義
映射接口
package com.eugeneheen.mapstruct.api.struct;
import com.yongyou.eshs.api.model.UserModel;
import com.yongyou.eshs.dao.dataobject.UserDo;
import org.mapstruct.Mapper;
@Mapper
public interface IUserStruct {
IUserStruct INSTANCE = Mappers.getMapper( IUserStruct.class );
UserDo modelToDo(UserModel userModel);
UserModel doToModel(UserDo user);
}
- 在
Service
中使用
public interface IUserService {
UserModel findById(Long id);
}
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserRepository userRepository;
@Override
public UserModel findById(Long id) {
UserDo user = this.userRepository.getOne(id);
// 此處团驱,由于映射定義未使用Spring注入,所以使用常量獲實例再調(diào)用映射方法
return IUserStruct.INSTANCE.toModel(user);
}
}
3.3 注入到Spring的使用示例
- 定義
映射接口
package com.eugeneheen.mapstruct.api.struct;
import com.yongyou.eshs.api.model.UserModel;
import com.yongyou.eshs.dao.dataobject.UserDo;
import org.mapstruct.Mapper;
// 使用@Mapper注解的componentModel屬性值制定為Spring榕订,實現(xiàn)Spring注入
@Mapper(componentModel = "spring")
public interface IUserStruct {
UserDo modelToDo(UserModel userModel);
UserModel doToModel(UserDo user);
}
- 在
Service
中使用
public interface IUserService {
UserModel findById(Long id);
}
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserRepository userRepository;
// 此處店茶,注入由Spring管理的映射實現(xiàn)
@Autowired
private IUserStruct userStruct;
@Override
public UserModel findById(Long id) {
UserDo user = this.userRepository.getOne(id);
return this.userStruct.toModel(user);
}
}
3.4 使用Spring擴展依賴的使用示例
待續(xù)......
4 常見問題
4.1 Maven
構(gòu)建出現(xiàn)生成了MapStruct的實現(xiàn)類,但該類只創(chuàng)建了對象劫恒,沒有進行賦值的問題
- 定義
映射接口
的模塊/工程贩幻,maven-compiler-plugin
插件,配置lombok-mapstruct-binding
依賴两嘴,且依賴版本由0.1.0
升級到0.2.0
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<!-- 此處丛楚,lombok依賴一定要放在,Mapstruct-processor依賴之前憔辫。否則趣些,生成了maptruct的實現(xiàn)類,但該類只創(chuàng)建了對象贰您,沒有進行賦值 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<!-- 如果是0.1.0 有可能出現(xiàn)生成了MapStruct的實現(xiàn)類坏平,但該類只創(chuàng)建了對象,沒有進行賦值 -->
<version>0.2.0</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
-
多項目
打包時锦亦,在父項目/打包模塊
的POM
中配置spring-boot-maven-plugin
插件時舶替,排除``依賴。詳細配置見3.1.1
章節(jié)杠园,SpringBoot
多模塊項目配置
5 MapStruct與各種BeanUtil性能比較
工具 | 十個對象復(fù)制1次 | 一萬個對象復(fù)制1次 | 一百萬個對象復(fù)制1次 | 一百萬個對象復(fù)制5次 |
---|---|---|---|---|
MapStruct | 0ms | 3ms | 96ms | 281ms |
Hutool的BeanUtil | 23ms | 102ms | 1734ms | 8316ms |
Spring的BeanUtils | 2ms | 47ms | 726ms | 3676ms |
Apache的BeanUtils | 20ms | 156ms | 10658ms | 52355ms |
測試數(shù)據(jù)僅供參考顾瞪,根據(jù)不同主機配置均有不同,單此處數(shù)據(jù)也能客觀表現(xiàn)性能