Mapstruct的简单使用

声明:
本文参考文章:
https://blog.csdn.net/datastructure18/article/details/120208842
https://blog.csdn.net/qq_44732146/article/details/119968376


一、背景
前两天,有个新同事问了我一个用mapstruct转换对象的问题。具体问题是这样的,对象里面包含做一个list,list里面的实体是该对象的内部类。因为不了解这块,一时间回答不了,于是上网查点资料研究研究。

二、mapstruct简介
Mapstruct一种实体类映射框架,能够通过Java注解将一个实体类的属性安全地赋值给另一个实体类。只需要定义一个映射器接口,声明需要映射的方法,在编译过程中,mapstruct会自动生成该接口的实现类,实现将源对象映射到目标对象的效果。

三、mapstruct与其他映射框架对比
实体类映射框架大致有两种:一种是运行期通过java反射机制动态映射;另一种是编译期动态生成getter/setter,在运行期直接调用框架编译好的class类实现实体映射。
由于mapstruct映射是在编译期间实现的,因此相比运行期的映射框架有以下几个优点:
1、 安全性高。
因为是编译期就实现源对象到目标对象的映射,如果编译器能够通过,运行期就不会报错;
2、 速度快。
速度快指的是运行期间直接调用实现类的方法,不会在运行期间使用反射进行转化。

四、mapstruct包分析、
Mapstruct主要有两个包:
1、 org.mapstruct:mapstruct:包含了映射相关的注解,如@Mapper、@Mapping等。
2、 org.mapstruct:mapstruct-processor:包含了注解处理器。用于处理注解相关的逻辑,如MappingProcessor等。

五、mapstruct配置
1、maven依赖:


   org.projectlombok
   lombok
   1.16.16



   org.mapstruct
   mapstruct
   1.3.1.Final



   org.mapstruct
   mapstruct-processor
   1.3.1.Final

2、相关插件:
安装mapstruct support后,在参数上按ctrl+左键,能够自动进入参数所在类文件,亲测好用。

3、 在pom文件中加入binding插件:
pom.xml -> build-> plugins 下加入 lombok-mapstruct-binding


   org.apache.maven.plugins
   maven-compiler-plugin
   3.5.1
   
      1.8
      1.8
      
         
            org.mapstruct
            mapstruct-processor
            1.3.1.Final
         
         
            org.projectlombok
            lombok
            1.18.20
         
         
            org.projectlombok
            lombok-mapstruct-binding
            0.2.0
         
      
   

用来解决:Error:(15, 13) java: No property named “id“ exists in source parameter(s). Did you mean “null“?

4、 本地启动增加参数:
Settings -> Build,Execution,Deployment -> Compiler 下,选择 User-local build process VM options (overrides Shared options):
添加参数

-Djps.track.ap.dependencies=false

六、代码实例:

package com.xld.test.mapstruct;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SourceObject {

    private String sourceName;

    private SourceAddrInfo sourceAddrInfo;

    private List sourceDetailInfoList;

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SourceAddrInfo{
        private String sourceAddr;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SourceDetailInfo{
        private String sourceDetail;
    }
}
package com.xld.test.mapstruct;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TargetObject {

    private String targetName;

    private TargetAddrInfo targetAddrInfo;

    private List targetDetailInfoList;

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TargetAddrInfo{
        private String targetAddr;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TargetDetailInfo{
        private String targetDetail;
    }
}
package com.xld.test.mapstruct;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.util.ArrayList;
import java.util.List;

@Mapper
public interface BuilderConverter {

    BuilderConverter INSTANCE = Mappers.getMapper(BuilderConverter.class);

    @Mapping(source = "sourceName",target = "targetName")
    TargetObject converterParam(SourceObject sourceObject);

    @Mapping(source = "sourceAddr",target = "targetAddr")
    TargetObject.TargetAddrInfo converterAddrInfo(SourceObject.SourceAddrInfo sourceAddrInfo);

    @Mapping(source = "sourceDetail",target = "targetDetail")
    TargetObject.TargetDetailInfo converterDetailInfo(SourceObject.SourceDetailInfo sourceDetailInfo);

    @Mappings({
            @Mapping(source = "sourceName",target = "targetName"),
            @Mapping(source = "sourceAddrInfo",target = "targetAddrInfo"),
            @Mapping(source = "sourceDetailInfoList",target = "targetDetailInfoList")
    })
    TargetObject converterObjectMappings(SourceObject sourceObject);



    public static void main(String[] args) {
        SourceObject sourceObject = SourceObject.builder()
                .sourceName("sourceName")
                .build();
        TargetObject targetObject = INSTANCE.converterParam(sourceObject);
        System.out.println("---------验证单个参数----------");
        System.out.println(sourceObject);
        System.out.println(targetObject);

        SourceObject.SourceAddrInfo sourceAddrInfo = SourceObject.SourceAddrInfo.builder()
                .sourceAddr("sourceAddr")
                .build();
        TargetObject.TargetAddrInfo targetAddrInfo = INSTANCE.converterAddrInfo(sourceAddrInfo);
        System.out.println("---------验证Addr对象----------");
        System.out.println(sourceAddrInfo);
        System.out.println(targetAddrInfo);

        SourceObject.SourceDetailInfo sourceDetailInfo = SourceObject.SourceDetailInfo.builder()
                .sourceDetail("sourceDetail")
                .build();
        TargetObject.TargetDetailInfo targetDetailInfo = INSTANCE.converterDetailInfo(sourceDetailInfo);
        System.out.println("---------验证Detail对象----------");
        System.out.println(sourceDetailInfo);
        System.out.println(targetDetailInfo);

        List sourceDetailInfoList = new ArrayList<>();
        sourceDetailInfoList.add(SourceObject.SourceDetailInfo.builder()
                .sourceDetail("sourceDetail1")
                .build());
        sourceDetailInfoList.add(SourceObject.SourceDetailInfo.builder()
                .sourceDetail("sourceDetail2")
                .build());
        sourceObject = SourceObject.builder()
                .sourceName("sourceName")
                .sourceAddrInfo(sourceAddrInfo)
                .sourceDetailInfoList(sourceDetailInfoList)
                .build();
        sourceObject.setSourceAddrInfo(sourceAddrInfo);
        targetObject = INSTANCE.converterObjectMappings(sourceObject);
        System.out.println("----------验证整个对象---------");
        System.out.println(sourceObject);
        System.out.println(targetObject);

    }
}

执行结果:

---------验证单个参数----------
SourceObject(sourceName=sourceName, sourceAddrInfo=null, sourceDetailInfoList=null)
TargetObject(targetName=sourceName, targetAddrInfo=null, targetDetailInfoList=null)
---------验证Addr对象----------
SourceObject.SourceAddrInfo(sourceAddr=sourceAddr)
TargetObject.TargetAddrInfo(targetAddr=sourceAddr)
---------验证Detail对象----------
SourceObject.SourceDetailInfo(sourceDetail=sourceDetail)
TargetObject.TargetDetailInfo(targetDetail=sourceDetail)
----------验证整个对象---------
SourceObject(sourceName=sourceName, sourceAddrInfo=SourceObject.SourceAddrInfo(sourceAddr=sourceAddr), sourceDetailInfoList=[SourceObject.SourceDetailInfo(sourceDetail=sourceDetail1), SourceObject.SourceDetailInfo(sourceDetail=sourceDetail2)])
TargetObject(targetName=sourceName, targetAddrInfo=TargetObject.TargetAddrInfo(targetAddr=sourceAddr), targetDetailInfoList=[TargetObject.TargetDetailInfo(targetDetail=sourceDetail1), TargetObject.TargetDetailInfo(targetDetail=sourceDetail2)])

你可能感兴趣的:(Mapstruct的简单使用)