MapStruct 入门使用

1. 概述

MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个Domain 对象转换为 DTO,涉及到类似之间对象转换的都可以用它来完成。其主要作用就是:Java bean mappings

详细信息可以参考最新版本的文档:MapStruct 1.3.0.Final Reference Guide

本文的内容也是来源于官方文档,只是简单的做一个简单的说明,方便理解和快速的使用。

2 引入依赖

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以上。

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);
  }

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); 

2.4 更新现有的 bean instances

使用@MappingTarget 传入一个bean,则更新的就是它:

@Mapper 
public interface CarMapper {
    void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
 }

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) {
    }
}

其生成的实现类中,会分别生成前置和后置的映射:

@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;
    }
}

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);
}

getMapper方法,相当于从其实现类中new一个无参构造方法,则可以通过它调用对应的方法。

4.2 spring依赖注入

@Mapper#componentModel属性,在定义的接口上加上

@Mapper(componentModel = "spring")

会自动生成实现类,并使用@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。可以用在类上和方法上。

你可能感兴趣的:(Java基础)