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
- Apache BeanUtils
- Spring BeanUtils
- 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
-
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
-
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
-
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.