In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article focuses on "Why to use MapStruct tool class", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "Why use the MapStruct tool class"!
Why do I need MapStruct?
First of all, let's talk about what kind of scenarios such as MapStruct are suitable for and why there are so many similar frameworks on the market.
Hierarchical structure is the most common and important structure in software architecture design. Many people are no stranger to three-tier architecture, four-tier architecture and so on.
Some people even say: "any problem in computer science can be solved by adding an indirect middle tier. If not, add two layers."
However, with more and more layers of software architecture, the data models of different levels are faced with the problem of mutual transformation. Typically, we can see all kinds of O in the code, such as DO, DTO, VO and so on.
In general, we use different data models at different levels for the same data model. For example, in the data storage layer, we use DO to abstract a business entity; in the business logic layer, we use DTO to represent data transfer objects; in the presentation layer, we encapsulate the objects into VO to interact with the front end.
Then, the data transparently transferred from the front end to the data persistence layer (from the persistence layer to the front end) requires mutual transformation between objects, that is, mapping between different object models.
Usually, we can use get/set and other methods to map fields one by one, such as:
PersonDTO.setName (personDO.getName ()); personDTO.setAge (personDO.getAge ()); personDTO.setSex (personDO.getSex ()); personDTO.setBirthday (personDO.getBirthday ())
However, writing such mapping code is a lengthy and error-prone task. The goal of similar frameworks such as MapStruct is to simplify the work as much as possible in an automated way.
The use of MapStruct
MapStruct is a code generator that greatly simplifies the implementation of mapping between Java bean types based on the "convention over configuration" approach. The generated mapping code uses pure method calls, so it is fast, type-safe, and easy to understand.
Convention over configuration, also known as programming by agreement, is a software design paradigm designed to reduce the number of decisions that software developers need to make and gain simple benefits without losing flexibility.
Suppose we have two classes that need to be converted to each other, namely PersonDO and PersonDTO. The class definition is as follows:
Public class PersonDO {private Integer id; private String name; private int age; private Date birthday; private String gender;} public class PersonDTO {private String userName; private Integer age; private Date birthday; private Gender gender;}
Let's demonstrate how to use MapStruct for bean mapping.
To use MapStruct, you first need to rely on its associated jar package, using maven dependencies as follows:
... 1.3.1.Final... Org.mapstruct mapstruct ${org.mapstruct.version}... Org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 org.mapstruct mapstruct-processor ${org.mapstruct.version}
Because MapStruct needs to generate conversion code in the compiler, you need to configure a reference to mapstruct-processor in the maven-compiler-plugin plug-in. This part will be introduced again later.
After that, we need to define an interface for mapping. The main code is as follows:
@ Mapper interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper (PersonConverter.class); @ Mappings (@ Mapping (source = "name", target = "userName") PersonDTO do2dto (PersonDO person);}
Use the annotation @ Mapper to define a Converter interface in which a do2dto method is defined. The input parameter type of the method is PersonDO and the output parameter type is PersonDTO. This method is used to convert PersonDO to PersonDTO.
The test code is as follows:
Public static void main (String [] args) {PersonDO personDO = new PersonDO (); personDO.setName ("Hollis"); personDO.setAge (26); personDO.setBirthday (new Date ()); personDO.setId (1); personDO.setGender (Gender.MALE.name ()); PersonDTO personDTO = PersonConverter.INSTANCE.do2dto (personDO); System.out.println (personDTO);}
Output result:
PersonDTO {userName='Hollis', age=26, birthday=Sat Aug 08 19:00:44 CST 2020, gender=MALE}
As you can see, we use MapStruct to convert PersonDO to PersonDTO perfectly.
As you can see in the above code, the use of MapStruct is relatively simple, relying mainly on the @ Mapper annotation.
But we know that in most cases, the attribute names, types, and so on between the two classes we need to convert to each other are not exactly the same, and there are cases where we don't want to map directly, so what should we do?
In fact, MapStruct has also done a good job in this respect.
MapStruct handles field mapping
First of all, we can clearly tell you that if the source object attributes in the two classes to be converted match the type and name of the target object attributes, the corresponding attributes will be automatically mapped.
So, what should we do if we encounter special circumstances?
How to map names with inconsistent names
As in the example above, name is used to represent the user name in PersonDO and userName is used to represent the user name in PersonDTO, so how to do parameter mapping.
At this point, you need to use the @ Mapping annotation. You only need to use the annotation on the method signature and specify the name of the source object and the name of the target object to be converted. For example, you can use the following way to map the value of name to userName:
@ Mapping (source = "name", target = "userName")
Types that can be mapped automatically
In addition to name inconsistencies, there is a special case of type inconsistencies, as in the above example, the user gender is represented by the String type in PersonDO and an enumeration of Genter is used in PersonDTO.
At this time, if the types are not consistent, the problem of mutual conversion needs to be involved.
In fact, MapStruct automatically maps some types, so there is no need for us to do any additional configuration. For example, in our example, we automatically convert String types to enumerated types.
In general, automatic type conversions can be done for the following situations:
Basic types and their corresponding packaging types.
Between the wrapper type of the basic type and the String type
Between String types and enumerated types
Custom constant
If we want to define a fixed value for some attributes during the transformation mapping process, we can use constant at this time
@ Mapping (source = "name", constant = "hollis")
How to map if the type is inconsistent
Again, in the above example, if we need to add the home address attribute to the Person object, we usually define a separate HomeAddress class in PersonoDTO to represent the home address, while in the Person class, we generally use the String type to represent the home address.
This requires the use of JSON to convert between HomeAddress and String, in which case MapStruct can also be supported.
Public class PersonDO {private String name; private String address;} public class PersonDTO {private String userName; private HomeAddress address;} @ Mapper interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper (PersonConverter.class); @ Mapping (source = "userName", target = "name") @ Mapping (target = "address", expression = "java (homeAddressToString (dto2do.getAddress ())") PersonDO dto2do (PersonDTO dto2do) Default String homeAddressToString (HomeAddress address) {return JSON.toJSONString (address);}}
We only need to define a method in PersonConverter (because PersonConverter is an interface, a default method can be defined in later versions of JDK 1.8), which is used to convert HomeAddress to String types.
Default method: a new language feature introduced by Java 8. The method marked with the keyword default and annotated by default needs to be implemented, and the subclass can choose to implement it or not.
Then on the dto2do method, the type conversion can be achieved by the following annotations:
@ Mapping (target = "address", expression = "java (homeAddressToString (dto2do.getAddress ())"))
The above are custom type conversions, and some are supported by MapStruct itself, such as the conversion between String and Date:
@ Mapping (target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
Above, I briefly introduce some commonly used methods of field mapping, which are also several scenarios that I often encounter in my work.
Performance of MapStruct
After talking about so many uses of MapStruct, we can see that the use of MapStruct is relatively simple, and the function of field mapping is very powerful, so what is its performance?
The time taken to perform 1000, 10000, 100000, and 1000000 mappings is 0ms, 1ms, 3ms, and 6ms, respectively.
As you can see, the time consuming of MapStruct is very short compared to several other tools.
So why can MapStruct perform so well?
In fact, the biggest difference between MapStruct and other types of frameworks is that compared with other mapping frameworks, MapStruct generates bean mappings at compile time, which ensures high performance, can feedback problems in advance, and allows developers to thoroughly check errors.
Remember when we introduced MapStruct dependencies earlier, especially when we added mapstruct-processor support to maven-compiler-plugin?
And we use a lot of annotations provided by MapStruct in our code, which allows MapStruct to generate bean mapping code directly at compile time, which is equivalent to writing a lot of setter and getter instead of us.
For example, we define the following Mapper in the code:
Mapper interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper (PersonConverter.class); @ Mapping (source = "userName", target = "name") @ Mapping (target = "address", expression = "java (homeAddressToString (dto2do.getAddress ())") @ Mapping (target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss") PersonDO dto2do (PersonDTO dto2do); default String homeAddressToString (HomeAddress address) {return JSON.toJSONString (address) }}
After the code is compiled, a PersonConverterImpl is automatically generated:
@ Generated (value = "org.mapstruct.ap.MappingProcessor", date = "2020-08-09T12:58:41+0800", comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0mm 181 (Oracle Corporation)") class PersonConverterImpl implements PersonConverter {@ Override public PersonDO dto2do (PersonDTO dto2do) {if (dto2do = = null) {return null } PersonDO personDO = new PersonDO (); personDO.setName (dto2do.getUserName ()); if (dto2do.getAge ()! = null) {personDO.setAge (dto2do.getAge ());} if (dto2do.getGender ()! = null) {personDO.setGender (dto2do.getGender (). Name ()) } personDO.setAddress (homeAddressToString (dto2do.getAddress ()); return personDO;}}
At run time, when mapping bean, the dto2do method of PersonConverterImpl is called directly, so there is nothing special to do, just set and get in memory.
So, because you do a lot of things at compile time, MapStruct will perform well at run time, and there is another benefit that you can advance the exposure of problems to compile time.
So that if there is a problem with the field mapping in the code, then the application cannot be compiled, forcing the developer to solve the problem.
At this point, I believe you have a deeper understanding of why you use the MapStruct tool class, so you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.