Simplify Java Bean Mapping with MapStruct: A Step‑by‑Step Guide
This article explains how to replace repetitive getter/setter code with MapStruct by showing dependency setup, defining source and target classes, creating mapper interfaces with @Mapping annotations, testing the conversion, and handling common integration issues such as Swagger conflicts.
During development, converting between similar entity objects often requires repetitive getter and setter calls, especially when the objects have overlapping but not identical fields, such as VO, DTO, BO, PO, and DAO.
MapStruct
MapStruct provides a concise way to map Java beans, reducing boilerplate code.
1. Add Maven dependencies
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>2. Official example
Create Car.java and CarDto.java:
public class Car {
private String make;
private int numberOfSeats;
private CarType type;
// constructor, getters, setters etc.
} public class CarDto {
private String make;
private int seatCount;
private String type;
// constructor, getters, setters etc.
}Define a mapper interface and annotate it with @Mapper:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}If field names differ, use @Mapping(source = "sourceField", target = "targetField") to specify the correspondence.
Test the mapping:
@Test
public void shouldMapCarToDto() {
// given
Car car = new Car("Morris", 5, CarType.SEDAN);
// when
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);
// then
assertThat(carDto).isNotNull();
assertThat(carDto.getMake()).isEqualTo("Morris");
assertThat(carDto.getSeatCount()).isEqualTo(5);
assertThat(carDto.getType()).isEqualTo("SEDAN");
}3. Apply in your own project
After setting up the project (e.g., the RuoYi front‑back separation template) and adding the MapStruct dependencies, create a mapper for your business entities:
import com.ruoyi.common.core.domain.basicinfomanage.BusMailList;
import com.ruoyi.common.core.domain.reportmanagement.BusDriverNoLoginRecord;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DriverNoLoginConvert {
DriverNoLoginConvert INSTANCE = Mappers.getMapper(DriverNoLoginConvert.class);
@Mappings({
@Mapping(source = "carNumber", target = "carNum"),
@Mapping(source = "driverNumber", target = "lastLoginNumber"),
@Mapping(target = "id", ignore = true)
})
BusDriverNoLoginRecord mailList2NoLoginRecord(BusMailList busMailList);
}Use the mapper in a loop:
longTimeNoLoginList.forEach(busMailList -> {
BusDriverNoLoginRecord record = DriverNoLoginConvert.INSTANCE.mailList2NoLoginRecord(busMailList);
});The conversion succeeds as verified by the test output.
4. Common pitfalls
If the build fails with "MapStruct – Couldn’t retrieve @Mapper annotation", it is usually caused by a conflict with springfox‑swagger2, which also includes MapStruct. Exclude MapStruct from the Swagger dependency:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</exclusion>
</exclusions>
</dependency>After excluding the duplicate, the project builds and MapStruct works as expected.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
The Dominant Programmer
Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
