What is it?

MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach.

The generated mapping code uses plain method invocations and thus is fast, type-safe, and easy to understand.

Why?

Multi-layered applications often require to map between different object models (e.g. entities and DTOs). Writing such mapping code is a tedious and error-prone task. MapStruct aims at simplifying this work by automating it as much as possible.

In contrast to other mapping frameworks, MapStruct generates bean mappings at compile-time, ensuring high performance, fast developer feedback, and thorough error checking.

How?

MapStruct is an annotation processor plugged into the Java compiler and can be used in command-line builds (Maven, Gradle, etc.) and from within your preferred IDE.

MapStruct uses sensible defaults but steps out of your way when it comes to configuring or implementing special behavior.

MapStruct

MapStruct is a code generation library that simplifies the process of mapping between Java bean types. It is particularly useful in applications where you need to convert between different object representations, such as Data Transfer Objects (DTOs) and entity classes in a Spring Boot application.

  • Reduce Boilerplate Code: By generating mapping code, MapStruct eliminates the need for manual mapping, reducing boilerplate code significantly.
  • Performance: Since the mapping code is generated at compile time, it offers better performance than runtime mapping frameworks that rely on reflection.
  • Maintainability: With a clear separation of concerns, your code becomes easier to maintain. DTOs and entities can evolve independently, and the mapping logic remains centralized.
  • Type Safety: Compile-time checks ensure that your mappings are correct, reducing runtime errors related to type mismatches.
  • Easier Refactoring: Since the mapping is done through defined interfaces and annotations, refactoring becomes less error-prone.
    
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.3.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.3.Final</version>
    <scope>provided</scope>
</dependency>

How to write Mapper:

    
       package com.example.demo;
        import com.example.demo.model.EmployeeDto;
        import com.example.demo.service.Address;
        import com.example.demo.service.Employee;
        import org.mapstruct.Mapper;
        import org.mapstruct.Mapping;
        import org.mapstruct.Named;
        import org.mapstruct.factory.Mappers;

        @Mapper(uses = AddressMapper.class)
        public interface CustomMapper {
            CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);

        //    @Mapping(target = "empId", source = "emp.empId")
            @Mapping(target = "empName", source = "emp.name")
            @Mapping(target = "isEligibleForVoting", source = "emp.age", qualifiedByName = "isEligibleForVoting")
            @Mapping(target = "empAddress", source = "emp.addr")
            @Mapping(target = "creationDate", expression = "java(new java.util.Date())")
            @Mapping(target = "personDetails", expression = "java(calculateEmpDetails(emp,addr))")
            EmployeeDto getEmpDetails(Employee emp, Address addr);

            @Named("isEligibleForVoting")
            default boolean isEligibleForVoting(int age) {
                return age >= 18; // Assuming 18 is the voting age
            }

            default String calculateEmpDetails(Employee emp, Address addr) {
                return emp.getName()+":"+addr.getAddrNm();
            }
        }