Are you still using BeanUtils? Try MapStruct, an elegant object conversion solution!

Java technology stack

www.javastack.cn

Follow to read more quality articles

The first time I saw MapStructthe time, I personally very happy. Because it coincides with my inner thoughts.

1 What is MapStruct?

1.1 The trouble with JavaBean

For code JavaBeanconversion between, it has been bothering me for a long time to do.

During development I see a lot of code between the business of JavaBeanmutual 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.

The first method through reflection is indeed more convenient, but now whether it is BeanUtils, the BeanCopierperformance 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 MapStructThe changes brought about

MapSturctIt is an annotation processor (annotation processor) that generates type-safe, high-performance and dependency-free JavaBean mapping code.

Grasp the key points:

  1. Annotation processor

  2. May be generated JavaBeanthat the mapping between the code

  3. Type safety, high performance, no dependency

From the literal understanding, we can know, this tool can help us achieve JavaBeanconversion between, by way of comment.

At the same time, as a tool, compared to handwriting, it should be more convenient and less error-prone.

2 MapStructGetting Started

Getting started is easy. I was based Mavenfor 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

MapperThat mapper, in general, is to write xxxMapperinterfaces.

Of course, it is not necessarily Mapperthe 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 @Mapperannotation 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 Orderthe OrderQueryParamconversion.

So, as an annotation processor, MapStructwhat 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 MapStructto 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.

Generated code

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.

Easy to 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 BeanUtilstools 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~

Guess you like

Origin blog.csdn.net/youanyyou/article/details/108413778