An overview of the

MapStruct is an annotation processor used to generate type-safe, high-performance, dependency free Java beans that can be mapped between two Javabeans

Common dynamic mappings

  1. Apache BeanUtils
  2. Spring BeanUtils
  3. cglib.BeanCopier

use

With MapStruct, you only need to define a mapper interface in which any mapping methods are declared. At compile time, MapStruct generates an implementation of this interface. This implementation uses pure Java method calls to map source and target objects, that is, there is no reflection.

1. Add dependencies

<properties>
    <org.mapstruct.version>1.4.2. The Final</org.mapstruct.version>
</properties>.<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
</dependencies>
Copy the code

2. Data preparation

@Data
@ToString
@AllArgsConstructor
public class PersonDTO {

    private String name;

    private String sex;

    private Integer age;
}

@Data
@ToString
public class PersonVO {

    private String name;

    private String sex;
}
Copy the code

Define the mapper

Now you need to install the Dto as VO, and you need to define the mapper

@Mapper
public interface PersonMapper {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    PersonVO dtoToVo(PersonDTO dto);
}
Copy the code

4, test,

 PersonDTO dto = new PersonDTO("AJin"."Male".24);
 PersonVO vo = PersonMapper.INSTANCE.dtoToVo(dto);
 System.out.println(vo);
Copy the code

5. Map fields with different field names

MapStruct maps our beans automatically because they have the same field name. So what if the bean we want to map has a different field name?

public class StudentDTO {

    private String nickname;
    
    private String sex;
    
}
@Data
@ToString
public class StudentVO {

    private String name;
    
     private String sex; 
}
Copy the code

Defining mapper

When mapping different field names, we need to configure their source field as their target field. To do this, we need to add the * @mappings comment. This annotation accepts an array of @Mapping* annotations that we will use to add target and source attributes

@Mapper
public interface StudentMapper {

    StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);

    @Mapping(target = "voName", source = "nickname")  // Attribute names are inconsistent
    @Mapping(target = "sex", ignore = true)         / / out
    StudentVO dtoToVo(StudentDTO dto);
}
Copy the code

6. Mapping methods with multiple source parameters

MapStruct supports mapping methods with multiple source parameters. For example, combine multiple entities into a single data transfer object

  1. data

    @Data
    @AllArgsConstructor
    public class ClassDTO {
    
        private String name;
    
        private Integer count;
    
    }
    
    @Data
    @ToString
    @AllArgsConstructor
    public class StudentDTO {
    
        private String name;
    
        private String sex;
    
        private Integer age;
    }
    
    @Data
    @ToString
    public class StudentVO {
    
        private String studentName;
    
        private String sex;
    
        private Integer age;
    
        private String className;
    }
    Copy the code
  2. Defining mapper

    @Mapper
    public interface StudentMapper {
    
        StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
    
    
        @Mapping(source = "studentDTO.name", target = "studentName")
        @Mapping(source = "classDTO.name", target = "className")
        StudentVO dtoToVo(StudentDTO studentDTO, ClassDTO classDTO);
    
    }
    Copy the code
  3. test

    public class Test {
        public static void main(String[] args) {
            StudentDTO studentDTO = new StudentDTO("AJin"."Male".24);
            ClassDTO classDTO = new ClassDTO("Non division 1".80); StudentVO vo = StudentMapper.INSTANCE.dtoToVo(studentDTO, classDTO); System.out.println(vo); }}Copy the code

The principle of

Annotations (target/generated-sources/ generated-source); And what’s actually done in the code package can be seen in the target/classes package.

conclusion

MapStruct is mainly used for object copying. It differs from BeanUtils in that it uses reflection to convert attribute assignments. It uses the compiler to generate regular methods, so it is faster and more efficient than reflection, and provides multiple configurations for different field names mapping, multiple data source mapping, custom methods, etc.