Backend Development 8 min read

Getting Started with MapStruct: High‑Performance Java Bean Mapping

This article introduces MapStruct, explains why traditional JavaBean conversion methods like reflection are inefficient, shows how to set up Maven dependencies, define entities and DTOs, write mapper interfaces, run tests, and highlights the performance, debugging, simplicity, and dependency‑free advantages of the generated code.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Getting Started with MapStruct: High‑Performance Java Bean Mapping

When the author first encountered MapStruct , they were excited because it aligned with their desire for a type‑safe, high‑performance, dependency‑free way to map JavaBeans.

1. The JavaBean conversion problem – Converting between JavaBeans often requires verbose code or reflection‑based utilities such as BeanUtils or BeanCopier , which either hurt performance or demand identical field names.

2. What MapStruct offers – As an annotation processor, MapStruct generates compile‑time mapping code that is type‑safe, fast, and has no runtime dependencies.

2.1 Getting started – Add the following Maven configuration to your pom.xml :

<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 Defining entity and DTO – Example Order entity and OrderQueryParam DTO classes are shown (fields: id, orderSn, receiverKeyword, status, orderType, sourceType).

@Data
public class Order {
    private Long id;
    private String orderSn;
    private String receiverKeyword;
    private Integer status;
    private Integer orderType;
    private Integer sourceType;
}

@Data
public class OrderQueryParam {
    private String orderSn;
    private String receiverKeyword;
    private Integer status;
    private Integer orderType;
    private Integer sourceType;
}

2.3 Writing the mapper – Create an interface annotated with @Mapper :

import com.homejim.mapstruct.dto.OrderQueryParam;
import com.homejim.mapstruct.entity.Order;
import org.mapstruct.Mapper;

@Mapper
public interface OrderMapper {
    OrderQueryParam entity2queryParam(Order order);
}

2.4 Testing the mapper – A JUnit test creates an Order instance, invokes the mapper, and asserts field equality.

@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 param = mapper.entity2queryParam(order);
    assertEquals(param.getOrderSn(), order.getOrderSn());
    // other assertions omitted for brevity
}

3. Analysis of MapStruct

3.1 High performance – Generated code runs like hand‑written code, avoiding the overhead of reflection.

3.2 Easy debugging – The implementation class (e.g., OrderMapperImpl ) can be inspected and stepped through in an IDE.

@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 param = new OrderQueryParam();
        param.setOrderSn(order.getOrderSn());
        param.setReceiverKeyword(order.getReceiverKeyword());
        param.setStatus(order.getStatus());
        param.setOrderType(order.getOrderType());
        param.setSourceType(order.getSourceType());
        return param;
    }
}

3.3 Simplicity – For straightforward mappings, only the interface and @Mapper annotation are needed; complex mappings can be customized with additional annotations.

3.4 No runtime dependency – The generated mapper is plain Java code, requiring no MapStruct library at runtime.

Overall, MapStruct provides a concise, performant, and maintainable solution for JavaBean mapping in backend projects.

JavaperformanceMavenMapStructAnnotation ProcessorBean Mapping
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.