• MapStruct的使用



     

    mapstruct 是一个bean copy、类型转换的类库,在编译时自动生成生成转换的硬编码代码,执行效率极高

    pom.xml

    在不使用 lombok 的情况下使用 mapstruct
    <properties>
        <java.version>1.8java.version>
        <mapstruct.version>1.5.3.Finalmapstruct.version>
    properties>
    
    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstructartifactId>
        <version>${mapstruct.version}version>
    dependency>
    
    <plugin>
        <groupId>org.apache.maven.pluginsgroupId>
        <artifactId>maven-compiler-pluginartifactId>
        <version>3.8.1version>
        <configuration>
            <source>${java.version}source>
            <target>${java.version}target>
            <annotationProcessorPaths>
                
                <path>
                    <groupId>org.mapstructgroupId>
                    <artifactId>mapstruct-processorartifactId>
                    <version>${mapstruct.version}version>
                path>
            annotationProcessorPaths>
        configuration>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    mapstruct-processor 用插件、依赖均可,上面的插件配置也可以直接换成依赖

    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstruct-processorartifactId>
    	<version>${mapstruct.version}version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

     

    同时使用 lombok、mapstruct

    二者都是在编译时自动生成代码,mapstruct 会用到 lombok 生成的getter、setter方法,引入时需要配置执行顺序

    <properties>
        <java.version>1.8java.version>
        <lombok.version>1.18.20lombok.version>
        <mapstruct.version>1.5.3.Finalmapstruct.version>
    properties>
    
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>${lombok.version}version>
        <optional>trueoptional>
    dependency>
    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstructartifactId>
        <version>${mapstruct.version}version>
    dependency>
    
    <plugin>
        <groupId>org.apache.maven.pluginsgroupId>
        <artifactId>maven-compiler-pluginartifactId>
        <version>3.8.1version>
        <configuration>
            <source>${java.version}source>
            <target>${java.version}target>
            <annotationProcessorPaths>
                
                <path>
                    <groupId>org.projectlombokgroupId>
                    <artifactId>lombokartifactId>
                    <version>${lombok.version}version>
                path>
                
                <path>
                    <groupId>org.mapstructgroupId>
                    <artifactId>mapstruct-processorartifactId>
                    <version>${mapstruct.version}version>
                path>
            annotationProcessorPaths>
        configuration>
    plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

     

    基本使用

    @Mapper  //此@Mapper是mapstruct的注解,不是mybatis的注解
    public interface UserMapper {
    
        //对象转对象
        UserVo bo2Vo(UserBo bo);
    
        //list转list
        List<UserVo> bos2Vos(List<UserBo> bos);
    
    	//支持多个source参数,source是实体类的会自动取对应的属性字段,source是普通类型的直接使用
        OrderRespBo po2OrderRespBo(OrderPo orderPo, Long userId);
        
        //如果target中的某些字段,在多个source中都有,需要指定取哪个source的
        @Mapping(source = "orderPo.id", target = "id")
        OrderRespBo po2OrderRespBo(OrderPo orderPo, UserPo userPo);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //获取mapper实例
    UserMapper userMapper = Mappers.getMapper(UserMapper.class);
    
    UserVo userVo = userMapper.bo2Vo(userBo);
    List<UserVo> userVos = userMapper.bos2Vos(userBos);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果修改mapper接口后编译、执行报错,可能是未生成最新的代码实现,可以尝试 mvn clean 后重新编译。

     

    作为bean注入

    //会作为bean放到spring容器中,也可以使用对应的常量 MappingConstants.ComponentModel.SPRING
    @Mapper(componentModel = "spring")
    public interface UserMapper {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @Resource
    private UserMapper userMapper;
    
    • 1
    • 2

     

    自定义类型转换

    其它常见的bean copy框架,往往需要字段名、数据类型相同,才会复制;mapstruct默认字段名相同就会复制,如果字段名相同,但mapstruct编译生成代码时无法实现对应数据类型的转换,编译时会报错,通不过编译

    //可以用uses引入需要的类型转换mapper,值是Class[],同名字段会自动使用引入的转换mapper中对应的方法进行转换
    @Mapper(uses = {ConvertMapper.class})
    public interface UserMapper {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    import org.mapstruct.Mapper;
    
    import java.util.Date;
    
    /**
     * 转换mapper
     */
    @Mapper //mapstruct的注解
    public interface ConvertMapper {
    
        /**
         * Date转时间戳
         *
         * @param date Date对象
         * @return Long
         */
        static Long date2Timestamp(Date date) {
            return date == null ? null : date.getTime();
        }
    
        /**
         * 时间戳转Date
         *
         * @param timestamp 时间戳
         * @return Date
         */
        static Date timestamp2Date(Long timestamp) {
            return timestamp == null ? null : new Date(timestamp);
        }
    
        /**
         * Integer 转 Boolean
         *
         * @param intValue 整型数据
         * @return Boolean
         */
        static Boolean int2Boolean(Integer intValue) {
            if (intValue == null || intValue == 0) {
                return Boolean.FALSE;
            }
            return Boolean.TRUE;
        }
    
        /**
         * Boolean 转 Integer
         *
         * @param boolValue 布尔类型数据
         * @return Integer
         */
        static Integer bool2Integer(Boolean boolValue) {
            if (boolValue == null || !boolValue) {
                return 0;
            }
            return 1;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 不局限于jdk自带的数据类型转换,也可以写自定义的实体类之间的转换
    • 生成代码时,mapstruct会自动使用当前mapper中已存在的方法、uses引入的mapper中的方法

     

    自定义字段映射

    @Mapper
    public interface UserMapper {
    
        //分别指定参数、目标类中的字段,可同时标注多个 @Mapping
        @Mapping(source = "tel", target = "phoneNumber")
        @Mapping(source = "name", target = "username")
        UserVo bo2Vo(UserBo bo);
    
    
        //同时使用多个时,也可以放在 @Mappings 中
        @Mappings({
            @Mapping(source = "tel", target = "phoneNumber"),
            @Mapping(source = "name", target = "username")
        })
        UserVo bo2Vo(UserBo bo);
    
    
        //只有1个参数时可以不带参数名,有多个参数时要带上参数名
        @Mapping(source = "userBo.userId", target = "userId")
        @Mapping(source = "orderBo.amount", target = "orderAmount")
        UserVo bo2Vo(UserBo userBo, OrderBo orderBo);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

     

    可以给target字段指定默认值,当target为null(即source为null)时,target会自动取默认值

    //source属性不是必需的,缺省时默认取target的值
    @Mapping(target = "username", defaultValue = "")
    @Mapping(source = "name", target = "username", defaultValue = "")
    
    • 1
    • 2
    • 3
  • 相关阅读:
    Obsidian 常用插件
    Netfilter之连接跟踪(Connection Tracking)和反向 SNAT(Reverse SNAT)
    中尺度混凝土二维有限元求解——运行弯曲、运行光盘、运行比较、运行半圆形(Matlab代码实现)
    【LeetCode】【剑指offer】【旋转数组的最小数字】
    31年前的Beyond演唱会,是如何超清修复的?
    利用WebShell拿Shell技巧
    windows 安装多个独立微信,设置不同快捷键
    关于windows下的System32与SysWOW64两个文件夹
    Hadoop分布式文件系统——HDFS
    ElasticSearch高阶操作
  • 原文地址:https://blog.csdn.net/chy_18883701161/article/details/127916574