Abstract

The current development of web backend uses multi-layer engineering structure, which needs to be converted to each other in VO,BO,DTO,DO and other data structures. These conversion code is some relatively simple field mapping, type conversion, repetitive work is relatively high, you can use some tools to free our hands

Technical solution

There are many schemes to implement class conversion, and different schemes have advantages and disadvantages, requiring developers to make their own choices

plan advantages disadvantages
Handwritten code 1. High flexibility 2. Convenient subsequent reconstruction 1. Repetitive work 2. Handwritten code is easy to miss some fields
Beanutils.copyproperties is implemented using reflection 2. Apache’s package efficiency is relatively low, while Spring’s package efficiency is acceptable Insufficient support for complex scenarios. The control copy granularity is too coarse. 2
mapstruct 1. High flexibility to support simple, complex, nested, custom extension and other means 2. Compile-time generation, no efficiency issues Not convenient for subsequent refactoring

Facilitate subsequent refactoring

Facilitating subsequent refactorings means that when you need to change a DTO field, you can use the compiler’s reference relationship to refactor it directly

In summary, mapstruct scheme is superior to Beanutils. Copy. Compared with handwriting scheme, mapstruct scheme has certain disadvantages, which needs to be selected. In my opinion, for field refactoring, this should be guaranteed through test cases rather than relying on editor functionality. In addition, the class reference relationship still exists after the transformation using Mapstruct, and the reconstruction can ensure no error by identifying the granularity of the class. If the error probability of manual party is taken into account, and the development efficiency of Mapstruct is obviously better.

implementation

  1. Importing dependency packages
< the properties > < org. Mapstruct. Version > 1.3.1. The Final < / org. Mapstruct. Version > < / properties >... <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> </dependencies>Copy the code
  1. Set up the annotation Processor for the Maven Compile Plugin
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> The < version > 3.8.1 < / version > < configuration > < source > 1.8 < / source > <! Depending on your project --> <target>1.8</target> <! -- depending on your project --> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> </path> <! -- other annotation processors --> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>Copy the code
  1. IDEA install a mapstruct plugin

With this plugin, you can find mapping class properties, some spelling verification

Common usage

By default, an implicit mapping occurs when the attribute value is the same as the name of the target entity

Other General conversions

Property values are different

@Mapping(target="dateEnd", source="end")
ExampleVO doToVO(ExampleDO do);
Copy the code

Collection object conversion

@Mapping(target="dateEnd", source="end")
ExampleVO doToVO(ExampleDO do);

List<ExampleVO> doToVOS(List<ExampleDO> dos)
Copy the code

JAVA constructor

Java representatives are invoked through Expression

@Mapping(target="dateEnd", expression="java(new java.util.Date())"
ExampleVO doToVO(ExampleDO do);
Copy the code

qualifiedByName

If the constructor fails, you can also customize the method and call it later

@Mapping(target="dateEnd", qualifiedByName="format", source="end")
ExampleVO doToVO(ExampleDO do);
@Named("format")
default Date formatDate(Long date) {
xxx
}
Copy the code

Interface Default implementation

Mapstruct is a user-defined interface, and then automatically generates the implementation class, so if you have a very custom transformation in the transformation class and you don’t want to use mapstruct to convert it, you can just use the default implementation of the interface

Of course, there are other functions that can be used, such as decorators, which are not listed here, but more rich functions that can be used in mapstruct details

reference

Blog.csdn.net/w605283073/…

Mapstruct details are used