写在最前面
使用场景,复杂的对象之间进行转换。 比如电商业务中,经常会出现一些订单之间转换的场景。 或者是使用它来做一些业务处理。
官网:https://mapstruct.org/ 参考1:https://blog.csdn.net/mobiusstrip/article/details/105674343 参考2:https://blog.csdn.net/u013217730/article/details/107212201
1 开发环境
这里列的是我的使用环境: java11,springboot,安装好lombok(高版本idea不用安装,直接引入依赖即可) idea中设置:
1.1 pom.xml
<?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 https://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.5.7</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>boot-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>boot-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<inherited>true</inherited>
<configuration>
<source>11</source>
<target>11</target>
<parameters>true</parameters>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</build>
</project>
2 文件结构介绍
以上,是源java文件,在编译之后:增加了一个UserConvertImpl的类。
2.1 各个java文件的内容
2.1.1 Score
package com.example.mapstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.math.BigDecimal;
import java.math.RoundingMode;
@Data
@NoArgsConstructor
@ToString
public class Score {
private BigDecimal mathScore;
private BigDecimal englishScore;
private BigDecimal chineseScore;
public BigDecimal getSum(){
return mathScore.add(englishScore).add(chineseScore).setScale(2, RoundingMode.HALF_UP);
}
public BigDecimal getAvg(){
return (mathScore.add(englishScore).add(chineseScore)).divide(new BigDecimal("3"), RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);
}
}
2.1.2 StudentDTO
package com.example.mapstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@ToString
public class StudentDTO {
private String id;
private String studentName;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private BigDecimal sumScore;
private BigDecimal avgScore;
}
2.1.3 UserConvert
这个接口是mapstruct的主要使用的位置,其实也可以定义为一个抽象类和抽象方法。这里导入了UserConvertUtil类。
package com.example.mapstruct;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@Mapper(componentModel = "spring", imports = {UserConvertUtil.class})
public interface UserConvert {
@Mappings({
@Mapping(target = "studentName", source = "userDTO.name"),
@Mapping(target = "id", expression = "java(String.valueOf(userDTO.getId()))"),
@Mapping(target = "createTime", source = "userDTO.createTime"),
@Mapping(target = "updateTime", source = "userDTO.updateTime"),
@Mapping(target = "sumScore", expression = "java(UserConvertUtil.getStudentSumScore(score))"),
@Mapping(target = "avgScore", expression = "java(score.getAvg())")
})
StudentDTO toStudent(UserDTO userDTO, Score score);
}
2.1.4 UserConvertUtil
这里特意使用了向转换类中引入其他类的方式。展示了另外的写法。
package com.example.mapstruct;
import java.math.BigDecimal;
public class UserConvertUtil {
public static BigDecimal getStudentSumScore(Score score){
return score.getSum();
}
}
2.1.5 UserDTO
package com.example.mapstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@ToString
public class UserDTO {
private Integer id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
2.1.6 TestService
package com.example.service;
public interface TestService {
String test();
}
2.1.7 TestServiceImpl
package com.example.service;
import com.example.mapstruct.Score;
import com.example.mapstruct.StudentDTO;
import com.example.mapstruct.UserConvert;
import com.example.mapstruct.UserDTO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Service
public class TestServiceImpl implements TestService{
@Resource
private UserConvert userConvert;
@Override
public String test() {
UserDTO userDTO = new UserDTO();
Score score = new Score();
userDTO.setId(1001);
userDTO.setCreateTime(LocalDateTime.now());
userDTO.setUpdateTime(LocalDateTime.now());
userDTO.setName("小刘");
score.setChineseScore(new BigDecimal("99.9"));
score.setMathScore(new BigDecimal("67.2"));
score.setEnglishScore(new BigDecimal("89.9"));
StudentDTO studentDTO = userConvert.toStudent(userDTO, score);
return studentDTO.toString();
}
}
2.1.8 TestController
package com.example.controller;
import com.example.service.TestService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class TestController {
@Resource
private TestService testService;
@GetMapping("/test")
public String test(){
return testService.test();
}
}
2.1.9 BootDemoApplication 启动类
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(BootDemoApplication.class, args);
}
}
2.2 运行结果
2.2.1 编译
当编译时,会自动生成一个 UserConvert 的实现类:
package com.example.mapstruct;
import org.springframework.stereotype.Component;
@Component
public class UserConvertImpl implements UserConvert {
public UserConvertImpl() {
}
public StudentDTO toStudent(UserDTO userDTO, Score score) {
if (userDTO == null && score == null) {
return null;
} else {
StudentDTO studentDTO = new StudentDTO();
if (userDTO != null) {
studentDTO.setStudentName(userDTO.getName());
studentDTO.setCreateTime(userDTO.getCreateTime());
studentDTO.setUpdateTime(userDTO.getUpdateTime());
}
studentDTO.setId(String.valueOf(userDTO.getId()));
studentDTO.setSumScore(UserConvertUtil.getStudentSumScore(score));
studentDTO.setAvgScore(score.getAvg());
return studentDTO;
}
}
}
2.2.2 启动项目运行
访问:http://localhost:8080/test 得到的是:
StudentDTO{id=‘1001’, studentName=‘小刘’, createTime=2022-03-03T20:06:12.707174, updateTime=2022-03-03T20:06:12.707174, sumScore=257.00, avgScore=85.70}
|