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; } } 复制代码
生成实现类位置如下: