使用场景,复杂的对象之间进行转换。
比如电商业务中,经常会出现一些订单之间转换的场景。
或者是使用它来做一些业务处理。
官网:https://mapstruct.org/
参考1:https://blog.csdn.net/mobiusstrip/article/details/105674343
参考2:https://blog.csdn.net/u013217730/article/details/107212201
这里列的是我的使用环境:
java11,springboot,安装好lombok(高版本idea不用安装,直接引入依赖即可)
idea中设置:
<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.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.7version>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>boot-demoartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>boot-demoname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>11java.version>
<maven.compiler.source>11maven.compiler.source>
<maven.compiler.target>11maven.compiler.target>
<org.mapstruct.version>1.4.2.Finalorg.mapstruct.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>${org.mapstruct.version}version>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${org.mapstruct.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>${maven-compiler-plugin.version}version>
<inherited>trueinherited>
<configuration>
<source>11source>
<target>11target>
<parameters>trueparameters>
<annotationProcessorPaths>
<path>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${org.mapstruct.version}version>
path>
<path>
<groupId>org.projectlombokgroupId>
<artifactId>lombok-mapstruct-bindingartifactId>
<version>0.2.0version>
path>
<path>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
path>
annotationProcessorPaths>
<showWarnings>trueshowWarnings>
configuration>
plugin>
plugins>
build>
project>
以上,是源java文件,在编译之后:增加了一个UserConvertImpl的类。
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);
}
}
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;
}
这个接口是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);
}
这里特意使用了向转换类中引入其他类的方式。展示了另外的写法。
package com.example.mapstruct;
import java.math.BigDecimal;
public class UserConvertUtil {
public static BigDecimal getStudentSumScore(Score score){
return score.getSum();
}
}
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;
}
package com.example.service;
public interface TestService {
String test();
}
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();
}
}
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();
}
}
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);
}
}
当编译时,会自动生成一个 UserConvert 的实现类:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
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;
}
}
}
访问: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}