Backend Development 9 min read

Introduction to MapStruct: What It Is, How to Use It, and Its Advantages

This article introduces MapStruct, a type‑safe, high‑performance, dependency‑free Java bean mapping annotation processor, explains the problems with manual and reflection‑based conversions, provides step‑by‑step Maven setup, entity/DTO definitions, mapper interface, and a JUnit test, and discusses its performance, debugging, and simplicity advantages.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Introduction to MapStruct: What It Is, How to Use It, and Its Advantages

When I first encountered MapStruct I was thrilled because it matched my desire for a clean, compile‑time solution to JavaBean conversion.

1. What is MapStruct?

1.1 The JavaBean Conversion Problem

Converting between JavaBeans often requires verbose code, reflection, or utilities such as BeanUtils or BeanCopier , which can hurt performance and demand identical field names.

Reflection‑based approaches are convenient but slower, while manual setters are error‑prone and time‑consuming.

1.2 What MapStruct Brings

MapStruct is a compile‑time annotation processor that generates type‑safe, high‑performance, dependency‑free mapping code.

Annotation processor

Generates mapping code for JavaBeans

Ensures type safety, high performance, and no runtime dependencies

It lets developers define mappings via annotations, reducing boilerplate and mistakes.

2. Getting Started with MapStruct

The example uses Maven for dependency management.

2.1 Adding 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 Defining Entity and DTO

Sample Order entity and OrderQueryParam DTO are shown below.

@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

The mapper interface is annotated with @Mapper and declares the conversion method.

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);
}

2.4 Testing the Mapping

@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());
    assertEquals(param.getOrderType(), order.getOrderType());
    assertEquals(param.getReceiverKeyword(), order.getReceiverKeyword());
    assertEquals(param.getSourceType(), order.getSourceType());
    assertEquals(param.getStatus(), order.getStatus());
}

3. Analysis of MapStruct

3.1 High Performance

Unlike reflection, the generated code runs as fast as hand‑written code because it is compiled directly.

3.2 Easy Debugging

The generated implementation (found under target/generated-sources/annotations ) can be inspected and stepped through in a debugger.

@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, simply declaring the interface is enough; special cases can be handled with additional annotations.

3.4 No Runtime Dependency

The generated code is independent and does not require MapStruct at runtime.

JavamavenMapStructAnnotation ProcessorBean Mapping
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.