MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个Domain 对象转换为 DTO,涉及到类似之间对象转换的都可以用它来完成。其主要作用就是:Java bean mappings
详细信息可以参考最新版本的文档:MapStruct 1.3.0.Final Reference Guide
本文的内容也是来源于官方文档,只是简单的做一个简单的说明,方便理解和快速的使用。
Spring项目中的简单使用,用Maven管理依赖,在pom文件中引入MapStruct:
1.3.0.Final
org.mapstruct
mapstruct
${org.mapstruct.version}
provided
...
org.apache.maven.plugins
maven-compiler-plugin
3.5.1
${java.version}
${java.version}
org.mapstruct
mapstruct-processor
${org.mapstruct.version}
注意,需要jdk1.8以上。
定义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);
}
可以使用@context注解,传入对象,起到一定的定制作用。
@Mapper
public interface AddressMapper {
@Mapping(source = "person.description", target = "description")
@Mapping(source = "address.houseNo", target = "houseNumber")
DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
使用@MappingTarget 传入一个bean,则更新的就是它:
@Mapper
public interface CarMapper {
void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
}
MapStruct同样支持没有getter/setter方法的映射。但是要求属性可以直接访问。
在接口中实现这两个注解标注的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) {
}
}
其生成的实现类中,会分别生成前置和后置的映射:
@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;
}
}
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);
}
getMapper方法,相当于从其实现类中new一个无参构造方法,则可以通过它调用对应的方法。
@Mapper#componentModel属性,在定义的接口上加上
@Mapper(componentModel = "spring")
会自动生成实现类,并使用@Component注解标注。
@Mapping注解:numberFormat 、dateFormat
使用注解@Mapper(uses=XXX.class)
MapStruct 会从XXX.class中查找满足转化的方法
@MappingTarget
在方法中传入对象,借助这个对象来定制转换方法。借助于@Context
使用qualifiers标志符,选择特定的方法来完成映射。qualifiedBy(class) 、qualifiedByName(使用@Name注解)
@Named:annotating the methods to qualify。可以用在类上和方法上。