MapStruct 是一个用于生成类型安全,高性能和无依赖的bean映射代码的注释处理器。竞争对手是 Selma 。
项目地址: https://gitee.com/SoftMeng/spring-boot-skill/tree/master/mapstruct-skill
MapStruct是一个Java 注释处理器,用于生成类型安全的bean映射类。
您所要做的就是定义一个mapper接口,该接口声明任何所需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用普通的Java方法调用来在源对象和目标对象之间进行映射,即没有反射或类似。
与手工编写映射代码相比,MapStruct通过生成繁琐且易于编写的代码来节省时间。遵循约定优于配置方法,MapStruct使用合理的默认值,但在配置或实现特殊行为时会采取措施。
与动态映射框架相比,MapStruct具有以下优势:
通过使用普通方法调用而不是反射来快速执行
编译时类型安全:只能映射相互映射的对象和属性,不会将订单实体意外映射到客户DTO等。
在构建时清除错误报告,如果
映射不完整(并非所有目标属性都已映射)
映射不正确(找不到合适的映射方法或类型转换)
包含所需的注释,例如@Mapping
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.0.Final</version>
</dependency>
复制代码
在编译,生成映射器实现的注释处理器,配置在pom.xml中build编译插件中。
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</path>
复制代码
IntelliJ IDEA 和 Eclipse IDE IntelliJ IDEA 可以配置对应的插件 Mapstruct Support Eclipse IDE 可以配置M2E插件 Eclipse IDE 需要在pom.xml中指定 <m2e.apt.activation>jdt_apt</m2e.apt.activation> 一般配置在pom.xml中build编译插件中
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>
-Amapstruct.suppressGeneratorTimestamp=true
</compilerArg>
<compilerArg>
-Amapstruct.suppressGeneratorVersionInfoComment=true
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
复制代码
|:--------:|:-----|:----| |选项|说明|默认值| |mapstruct. suppressGeneratorTimestamp|如果设置为true,@Generated则抑制在生成的映射器类中的注释中创建时间戳。|false| |mapstruct. suppressGeneratorVersionInfoComment|如果设置为true,则抑制在生成的映射器类comment中的@Generated注释中创建属性。注释包含有关MapStruct版本以及用于注释处理的编译器的信息。|false| |mapstruct.defaultComponentModel|组件模型的名称(请参阅)基于应生成的映射器。|default| |mapstruct.unmappedTargetPolicy|如果未使用源值填充映射方法的目标对象的属性,则应用默认报告策略。|WARN|
|:--------:|:-----|:----| |支持的值|说明|检索实例| |default|映射器不使用组件模型,通常通过检索实例|Mappers#getMapper(Class)| |cdi|生成的映射器是一个应用程序范围的CDI bean|@Inject| |spring|生成的映射器是一个单例范围的Spring bean|@Autowired| |jsr330|生成的映射器使用{@code @Named}进行注释|@Inject|
要创建映射器,只需使用所需的映射方法定义Java接口,并使用注释对其进行 org.mapstruct.Mapper 注释
@Mapper
public interface CardMapper {
CardMapper INSTANCE = Mappers.getMapper(CardMapper.class);
/**
* card 转 CardDto .
*
* @param card
* @return
*/
@Mapping(target = "maker", source = "make")
CardDto dto(Card card);
/**
* CardDt 转 card .
*
* @param cardDto
* @return
*/
@Mapping(target = "make", source = "maker")
Card entity(CardDto cardDto);
}
复制代码
该@Mapper注释将使得 MapStruct 代码生成器创建的执行 CardMapper 过程中生成时的界面。
在生成的方法实现中,源类型(例如 Card )中的所有可读属性将被复制到目标类型中的相应属性中(例如 CardDto )
@Mapping
MapStruct 的一般原理是生成尽可能多的代码,就像你自己亲自编写代码一样。特别地,这意味着通过普通的 etter / setter 调用而不是反射或类似的方法将值从源复制到目标。
MapStruct 会考虑源和目标类型的所有公共属性。这包括在超类型上声明的属性。
MapStruct 会进行某些隐式转换。
public class CardMapperImpl implements CardMapper {
@Override
public CardDto dto(Card card) {
if ( card == null ) {
return null;
}
CardDto cardDto = new CardDto();
cardDto.setMaker( card.getMake() );
cardDto.setName( card.getName() );
cardDto.setNote( card.getNote() );
cardDto.setImage( card.getImage() );
cardDto.setCreateTime( card.getCreateTime() );
cardDto.setPrice( card.getPrice() );
return cardDto;
}
@Override
public Card entity(CardDto cardDto) {
if ( cardDto == null ) {
return null;
}
Card card = new Card();
card.setMake( cardDto.getMaker() );
card.setName( cardDto.getName() );
card.setNote( cardDto.getNote() );
card.setImage( cardDto.getImage() );
card.setCreateTime( cardDto.getCreateTime() );
card.setPrice( (int) cardDto.getPrice() );
return card;
}
}
复制代码
生成实现类位置如下: