1. 概述
MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个Domain 对象转换为 DTO,涉及到类似之间对象转换的都可以用它来完成。其主要作用就是:Java bean mappings
详细信息可以参考最新版本的文档:MapStruct 1.3.0.Final Reference Guide
本文的内容也是来源于官方文档,只是简单的做一个简单的说明,方便理解和快速的使用。
2 引入依赖
Spring项目中的简单使用,用Maven管理依赖,在pom文件中引入MapStruct:
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
12345678910111213141516171819202122232425
注意,需要jdk1.8以上。
2. 简单使用
2.1 基础mappings
定义Mapper接口
@Mapper
public interface CarMapper {
@Mapping(source = "make", target = "manufacturer")
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
@Mapping(source = "name", target = "fullName")
PersonDto personToPersonDto(Person person);
}
123456789
2.2 Adding custom methods to mappers
可以使用@context注解,传入对象,起到一定的定制作用。
2.3 多个参数来源的映射
@Mapper
public interface AddressMapper {
@Mapping(source = "person.description", target = "description")
@Mapping(source = "address.houseNo", target = "houseNumber")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
12345
2.4 更新现有的 bean instances
使用@MappingTarget 传入一个bean,则更新的就是它:
@Mapper
public interface CarMapper {
void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
}
1234
2.5 Mappings with direct field access
MapStruct同样支持没有getter/setter方法的映射。但是要求属性可以直接访问。
2.6 @AfterMapping和@BeforeMapping
在接口中实现这两个注解标注的default方法,会在映射前后调用:
@Mapper(componentModel = "spring")
public interface AddressMapper {
AddressMapper MAPPER = Mappers.getMapper(AddressMapper.class);
@Mapping(target = "name", source = "address.name")
@Mapping(target = "gender", source = "person.gender")
PersonAddressDto convert(Address address, Person person, @MappingTarget PersonAddressDto target);
@AfterMapping
default void afterMapping(Address address, @MappingTarget PersonAddressDto target) {
}
@BeforeMapping
default void beforeMapping(Person person, @MappingTarget PersonAddressDto target) {
}
}
1234567891011121314151617
其生成的实现类中,会分别生成前置和后置的映射:
@Component
public class AddressMapperImpl implements AddressMapper {
@Override
public PersonAddressDto convert(Address address, Person person, PersonAddressDto target) {
if ( address == null && person == null ) {
return null;
}
//前置
beforeMapping( person, target );
if ( address != null ) {
target.setName( address.getName() );
}
if ( person != null ) {
target.setGender( person.getGender() );
}
//后置
afterMapping( address, target );
return target;
}
}
1234567891011121314151617181920212223
4. Retrieving a mapper
4.1 The Mappers factory
org.mapstruct.factory.Mappers class. Just invoke the getMapper() method。
例如:
@Mapper(componentModel = "spring")
public interface AddressMapper {
AddressMapper MAPPER = Mappers.getMapper(AddressMapper.class);
@Mapping(target = "name", source = "address.name")
@Mapping(target = "gender", source = "person.gender")
PersonAddressDto convert(Address address, Person person);
}
123456789
getMapper方法,相当于从其实现类中new一个无参构造方法,则可以通过它调用对应的方法。
4.2 spring依赖注入
@Mapper#componentModel属性,在定义的接口上加上
@Mapper(componentModel = "spring")
1
会自动生成实现类,并使用@Component注解标注。
5. 数据类型转换
5.1 隐士类型转换
@Mapping注解:numberFormat 、dateFormat
5.2 Controlling nested bean mappings
5.3 Invoking other mappers
使用注解@Mapper(uses=XXX.class)
MapStruct 会从XXX.class中查找满足转化的方法
5.4 Passing the mapping target type to custom mappers
@MappingTarget
5.5 Passing context or state objects to custom methods
在方法中传入对象,借助这个对象来定制转换方法。借助于@Context
5.6 Mapping method selection based on qualifiers
使用qualifiers标志符,选择特定的方法来完成映射。qualifiedBy(class) 、qualifiedByName(使用@Name注解)
@Named:annotating the methods to qualify。可以用在类上和方法上。