mapstract实体转换工具

实体类转换工具

本文档描述mapstract实体转换工具的引入

1 前言

mapstract相较于BeanUtils之类属性复制工具,效率高出很多,因为mapstrac采用的是java方法调用实现的属性复制,而不是反射。代码编译时,mapstrac会自动生成实现类的字节码文件(存在问题会编译不通过),反编译打开可看到实现类是通过get、set方法进行的属性赋值转换,经过测试,百万次转可以在几十毫秒内完成

2 功能引入

2.1 引入依赖

由于项目使用的是java8,引入如下依赖

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.1.Final</version>
</dependency>

由于mapstract在代码编译时会生成实现类,而实现类里主要是使用get\set方法进行属性的赋值,这和Lombok的功能存在冲突,所以要在编译插件引入如下代码

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven.compiler.plugin.version}</version>
    <inherited>true</inherited>
    <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <skip>true</skip>
    <encoding>${project.build.sourceEncoding}</encoding>
    <annotationProcessorPaths>
        <path>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${mapstruct.version}</version>
        </path>
        <path>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </path>
    </annotationProcessorPaths>
    </configuration>
</plugin>

2.2 编写基础功能接口

基础功能接口具有四个基本功能接口,代码如下

public interface BaseConvert<SOURCE,TARGET> {
​
    /** @description: 基础转换方法
     当SOURCE的全部字段名和TARGET的一致时,把SOURCE类型转为TARGET类型,
      当存在不一致的字段名时,请在子类里重写该方法,并使用{@link org.mapstruct.Mappings}注解
     将不一致的字段建立映射关系,一点要注意source和target的顺序,例如
     @Mappings({
      @Mapping(source = "categoryCode",target = "code"),
      @Mapping(source = "categoryName",target = "name")
     })
     */
    @InheritConfiguration
    TARGET to(SOURCE source);
​
    @InheritConfiguration
    List<TARGET> to(Collection<SOURCE> sources);
   
    /** 将TARGET类型的对象转为SOURCE类型 */
    @InheritInverseConfiguration
    SOURCE from(TARGET source);
    
    @InheritInverseConfiguration
    List<SOURCE> from(Collection<TARGET> sources);
​
}

其中@InheritConfiguration注解写在正向的

2.3 编写实体类转换接口

实体类转换接口继承基础功能接口,指定SOURCE和TARGET的顺序,每两个实体之间需要一个转换类, 例如如下的转换接口,不一致的字段映射写在{@link org.mapstruct.Mapping}注解里,可以写多个,也可以整体用{@link org.mapstruct.Mappings}注解包起来,注意source和target的顺序

​
@Mapper(componentModel = "spring")
public interface UserDTOWithVoConvert extends BaseConvert<UserDTO, UserVO> {
​
   @Override
   @Mapping(source = "categoryCode",target = "code")
   @Mapping(source = "name.firstName",target = "firstName")
   @Mapping(source = "name.lastName",target = "lastName")
// @Mapping(target = "name",expression = "java(userDTO.getName().getFirstName() + \".\" + userDTO.getName().getLastName())")
   @Mapping(target = "name",expression = "java(userDTO.getFullName())")
   @Mapping(target = "description",expression = "java(org.springframework.util.StringUtils.trimAllWhitespace(userDTO.getDescription()))")
   @Mapping(target = "cnBirthday",expression = "java(userDTO.getCNBirthday())")
   @Mapping(source = "birthday",target = "birthday",dateFormat = "yyyy-MM-dd")
   @Mapping(source = "adulted",target = "adulted")
   @Mapping(source = "healthy",target = "healthy",nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
   @InheritConfiguration
   UserVO to(UserDTO userDTO);
​
   @Override
   @Mapping(target = "name",expression = "java(source.getNameObject())")
   @InheritInverseConfiguration
   UserDTO from(UserVO source);
   
   
    default Integer boolenToInteger(Boolean bool){
      if(bool == null){
         return null;
      }
      if(bool){
         return 1;
      }
      return 0;
   }
   
 default Boolean boolenToInteger(Integer number){
      if(number == null){
         return null;
      }
      if(number==1){
         return true;
      }
      return false;
   }
​
}

2.4 工具类

public class ConvertUtil{
​
​
    public static <SOURCE,TARGET> TARGET convertTo(SOURCE source,Class<? extends BaseConvert<SOURCE,TARGET>> convertClass){
        BaseConvert<SOURCE, TARGET> convert = getConvert(convertClass);
     return convert.to(source);
    }
    
    
    public static <SOURCE,TARGET> List<TARGET> convertTo(Collection<SOURCE> sources, Class<? extends BaseConvert<SOURCE,TARGET>> convertClass){
        if ( sources == null ) {
           return null;
        }
        BaseConvert<SOURCE, TARGET> convert = getConvert(convertClass);
        return convert.to(sources);
    }
    
    public static <SOURCE,TARGET> SOURCE convertFrom(TARGET source,Class<? extends BaseConvert<SOURCE,TARGET>> convertClass){
    if ( sources == null ) {
           return null;
        }
       BaseConvert<SOURCE, TARGET> convert = getConvert(convertClass);
        return convert.from(source);
    }
    
    public static <SOURCE,TARGET> List<SOURCE> convertFrom(Collection<TARGET> sources, Class<? extends BaseConvert<SOURCE,TARGET>> convertClass){
        if ( sources == null ) {
           return null;
        }
           BaseConvert<SOURCE, TARGET> convert = getConvert(convertClass);
        return convert.from(sources);
    }
    
    //从容器中获取转换接口实现类
    public static <SOURCE,TARGET> BaseConvert<SOURCE,TARGET> getConvert(Class<? extends BaseConvert<SOURCE,TARGET>> convertClass){
      return SpringContextUtil.getBean(convertClass);
    }
    
}

//SpringContextUtil里保存了spring容器的上下文

3 使用方法

直接使用ConvertUtil的方法进行调用即可,例如

        UserVO userVO = ConvertUtil.convertTo(userDTO,UserDTOWithVoConvert.class);
        
        userDTO = ConvertUtil.convertFrom(userVO,UserDTOWithVoConvert.class);
        
        List<UserVO> userVOList = ConvertUtil.convertTo(userDTOList,UserDTOWithVoConvert.class);
        
        List<UserDTO> dtoList = ConvertUtil.convertFrom(userVOList,UserDTOWithVoConvert.class);
​
​

4 进阶功能

更多功能可参考官方文档进行使用 https://mapstruct.org/documentation/1.3/reference/html/

5 注意事项

除了和Lombok搭配使用需要在编译插件添加对应的编译依赖外,集成swagger2时,要将其中的mapstract依赖排除掉

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.2.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>mapstruct</artifactId>
                    <groupId>org.mapstruct</groupId>
                </exclusion>
            </exclusions>
        </dependency>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值