Java technology stack
www.javastack.cn
Follow to read more quality articles
The first time I saw MapStruct
the time, I personally very happy. Because it coincides with my inner thoughts.
1 What is MapStruct?
1.1 The trouble with JavaBean
For code
conversion between, it has been bothering me for a long time to do.JavaBean
During development I see a lot of code between the business of
mutual conversion between the very perception of influence, but had to exist. One way I thought of later was to use reflection or write a lot of converters myself.JavaBean
The first method through reflection is indeed more convenient, but now whether it is BeanUtils
, the BeanCopier
performance will be affected when using reflection. Although we can cache reflection information to improve performance.
But in this case, the mapping needs to be the same for the type and name. In many cases, because the nouns used by different teams are different, a lot of manual set/get functions are still needed.
The second type is a waste of time, and the method must be modified when adding new fields. However, since no reflection is required, its performance is very high.
1.2 MapStruct
The changes brought about
MapSturct
It is an annotation processor (annotation processor) that generates type-safe, high-performance and dependency-free JavaBean mapping code.
Grasp the key points:
Annotation processor
May be generated
JavaBean
that the mapping between the codeType safety, high performance, no dependency
From the literal understanding, we can know, this tool can help us achieve
conversion between, by way of comment.JavaBean
At the same time, as a tool, compared to handwriting, it should be more convenient and less error-prone.
2 MapStruct
Getting Started
Getting started is easy. I was based Maven
for project management package jar.
2.1 Introducing dependencies
<properties>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
2.2 Create entity and dto objects
This class is taken from a certain order system on github.
@Data
public class Order {
/**
*订单id
*/
private Long id;
/**
* 订单编号
*/
private String orderSn;
/**
* 收货人姓名/号码
*/
private String receiverKeyword;
/**
* 订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单
*/
private Integer status;
/**
* 订单类型:0->正常订单;1->秒杀订单
*/
private Integer orderType;
/**
* 订单来源:0->PC订单;1->app订单
*/
private Integer sourceType;
}
Corresponding query parameters
@Data
public class OrderQueryParam {
/**
* 订单编号
*/
private String orderSn;
/**
* 收货人姓名/号码
*/
private String receiverKeyword;
/**
* 订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单
*/
private Integer status;
/**
* 订单类型:0->正常订单;1->秒杀订单
*/
private Integer orderType;
/**
* 订单来源:0->PC订单;1->app订单
*/
private Integer sourceType;
}
2.3 Write Mapper
Mapper
That mapper, in general, is to write xxxMapper
interfaces.
Of course, it is not necessarily Mapper
the end. It's just the official writing. In this introductory example, the corresponding interface is as follows
import com.homejim.mapstruct.dto.OrderQueryParam;
import com.homejim.mapstruct.entity.Order;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper
public interface OrderMapper {
OrderQueryParam entity2queryParam(Order order);
}
Simple mapping (field and type of match), have only one request, to write on the interface @Mapper
annotation can be.
Then in the method, the input parameter corresponds to the object to be transformed, the return value corresponds to the transformed object, and the method name can be arbitrary.
2.4 Testing
Write a test class to test it.
@Test
public void entity2queryParam() {
Order order = new Order();
order.setId(12345L);
order.setOrderSn("orderSn");
order.setOrderType(0);
order.setReceiverKeyword("keyword");
order.setSourceType(1);
order.setStatus(2);
OrderMapper mapper = Mappers.getMapper(OrderMapper.class);
OrderQueryParam orderQueryParam = mapper.entity2queryParam(order);
assertEquals(orderQueryParam.getOrderSn(), order.getOrderSn());
assertEquals(orderQueryParam.getOrderType(), order.getOrderType());
assertEquals(orderQueryParam.getReceiverKeyword(), order.getReceiverKeyword());
assertEquals(orderQueryParam.getSourceType(), order.getSourceType());
assertEquals(orderQueryParam.getStatus(), order.getStatus());
}
The test passed without any problems.
3 MapStruct analysis
Above, I wrote three steps to achieve from Order
the OrderQueryParam
conversion.
So, as an annotation processor, MapStruct
what advantages does the generated code have?
3.1 High performance
This is relative to reflection, which needs to read the contents of the bytecode, which will cost more. Learn reflection and read " Java reflection, I will definitely see this " this article is enough! Follow the public number Java technology stack to read more Java technology dry goods tutorials.
Through MapStruct
to the generated code, which is similar to the human hand. Speed can be guaranteed.
The code generated in the previous example can be seen after compilation. You can see it in target/generated-sources/annotations.
Corresponding code
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2019-08-02T00:29:49+0800",
comments = "version: 1.3.0.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)"
)
public class OrderMapperImpl implements OrderMapper {
@Override
public OrderQueryParam entity2queryParam(Order order) {
if ( order == null ) {
return null;
}
OrderQueryParam orderQueryParam = new OrderQueryParam();
orderQueryParam.setOrderSn( order.getOrderSn() );
orderQueryParam.setReceiverKeyword( order.getReceiverKeyword() );
orderQueryParam.setStatus( order.getStatus() );
orderQueryParam.setOrderType( order.getOrderType() );
orderQueryParam.setSourceType( order.getSourceType() );
return orderQueryParam;
}
}
You can see that it generates an implementation class, and the code is similar to our handwriting, easy to understand.
3.2 Easy to debug
In the code we generate, we can easily debug.
When using reflection, if there is a problem, it is often difficult to find the cause.
3.3 Relatively easy to use
If it is completely mapped, it is definitely not as simple as reflection. Using similar BeanUtils
tools to get a statement. However, if special matching (special type conversion, many-to-one conversion, etc.) is required, it is relatively simple.
Basically, when using it, we only need to declare an interface, write the corresponding method under the interface, and it can be used. Of course, if there are special circumstances, additional processing is required.
3.4 Code independence
The generated code is opposite and has no runtime dependencies.
Author: A intake desk
Source: https://www.cnblogs.com/homejim/
The copyright of this article belongs to the author and the blog garden, welcome to reprint, but without the author’s consent, this statement must be retained, and the original link must be given in an obvious place on the article page, otherwise the right to pursue legal responsibility is reserved.
Recent hot articles:
1. I wrote a piece of logic in Java 8, but my colleagues couldn't understand it directly
2. Spring Boot study notes, this is too complete!
3. Hang Tomcat, Undertow performance is very explosive! !
4. Spring Boot is too cruel, release 3 versions at a time!
5. How does Spring Boot integrate Redis quickly?
6、The latest release of "Java Development Manual (Songshan Edition)"
7. Spring Boot Redis implements distributed locks, which is so fragrant!
8. Chinese open sourced a small and complete Java tool library !
9. The Chinese open sourced a super easy to use Redis client! !
10、My colleague wrote a hidden bug, and I checked it for 3 days!
Scan the QR code to follow the official account of the Java Technology Stack to read more dry goods.
Click " Read Original " to get a complete list of interview questions~