• MapStruct入门使用


    背景

    在实际的项目开发中会大量的使用POJO作为数据载体,通常有如下的:

    实体名实体含义说明
    DOData Object与数据库表结构一一对应,通过DAO层向上传输数据源对象
    DTOData Transfer Object数据传输对象,Service或Manager向外传输的对象
    BOBusiness Object业务对象,由Service层输出的封装业务逻辑的对象
    VOView Object显示层对象,通常是 Web 向模板渲染引擎层传输的对象
    • Spring BeanUtils
    • Apache BeanUtils
    • Orika的MapperFacade和MapperFactory
    • MapStruct
      可以选择MapStruct,功能十分强大,而且很灵活,可以满足我们需要的各种需求。

    入门案例

    Maven项目引入

    只需要在pom.xml文件中加入以下依赖即可:

    ...
    <properties>
            <java.version>1.8java.version>
            <mapstruct.version>1.3.1.Finalmapstruct.version>
        properties>
    ...
        <dependencies>
            <dependency>
                <groupId>org.mapstructgroupId>
                <artifactId>mapstructartifactId>
                <version>${mapstruct.version}version>
            dependency>
        dependencies>
    ...
        <build>
            <plugins>
                <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>
            plugins>
        build>
    ...
    
    • 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

    源对象

    在这里插入图片描述

    CarDO

    package com.linfanchen.springboot.lab.mapstruct.domain;
    
    public class CarDO {
        /**
         * 主键ID
         */
        private Integer id;
    
        /**
         * 名称
         */
        private String name;
    
        /**
         * 品牌
         */
        private String brand;
    
        /**
         * 车价
         */
        private Integer price;
    
        /**
         * 轮胎属性
         */
        private TyreDO tyreDO;
    
        /**
         * 汽车图片
         */
        private String images;
    
        public String getImages() {
            return images;
        }
    
        public void setImages(String images) {
            this.images = images;
        }
    
        public TyreDO getTyreDO() {
            return tyreDO;
        }
    
        public void setTyreDO(TyreDO tyreDO) {
            this.tyreDO = tyreDO;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public void setPrice(Integer price) {
            this.price = price;
        }
    }
    
    
    • 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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    TyreDO

    package com.linfanchen.springboot.lab.mapstruct.domain;
    
    /**
     * 轮胎
     */
    public class TyreDO {
        /**
         * 主键ID
         */
        private Integer id;
    
        /**
         * 轮胎名称
         */
        private String name;
    
        /**
         * 轮胎尺寸
         */
        private Integer size;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getSize() {
            return size;
        }
    
        public void setSize(Integer size) {
            this.size = size;
        }
    }
    
    
    • 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

    目标对象

    CarBO

    package com.linfanchen.springboot.lab.mapstruct.bo;
    
    import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
    
    import java.util.List;
    
    /**
     * 汽车业务对象
     */
    public class CarBO {
        /**
         * 主键ID
         */
        private Integer id;
    
        /**
         * 名称
         */
        private String name;
    
        /**
         * 品牌
         */
        private String brand;
    
        /**
         * 车价
         */
        private Integer price;
    
        /**
         * 轮胎属性
         */
        private TyreDO tyreDO;
    
        /**
         * 汽车图片
         */
        private String images;
    
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public void setPrice(Integer price) {
            this.price = price;
        }
    
        public TyreDO getTyreDO() {
            return tyreDO;
        }
    
        public void setTyreDO(TyreDO tyreDO) {
            this.tyreDO = tyreDO;
        }
    
        public String getImages() {
            return images;
        }
    
        public void setImages(String images) {
            this.images = images;
        }
    }
    
    • 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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    CarDetailBO

    package com.linfanchen.springboot.lab.mapstruct.bo;
    
    import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
    
    import java.util.List;
    
    /**
     * 汽车业务对象
     */
    public class CarDetailBO {
        /**
         * 主键ID
         */
        private Integer carId;
    
        /**
         * 名称
         */
        private String carName;
    
        /**
         * 品牌
         */
        private String carBrand;
    
        /**
         * 车价
         */
        private Integer price;
    
        /**
         * 轮胎属性
         */
        private TyreDO tyreDetail;
    
        /**
         * 汽车图片
         */
        private List<String> images;
    
    
        public Integer getCarId() {
            return carId;
        }
    
        public void setCarId(Integer carId) {
            this.carId = carId;
        }
    
        public String getCarName() {
            return carName;
        }
    
        public void setCarName(String carName) {
            this.carName = carName;
        }
    
        public String getCarBrand() {
            return carBrand;
        }
    
        public void setCarBrand(String carBrand) {
            this.carBrand = carBrand;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public void setPrice(Integer price) {
            this.price = price;
        }
    
        public TyreDO getTyreDetail() {
            return tyreDetail;
        }
    
        public void setTyreDetail(TyreDO tyreDetail) {
            this.tyreDetail = tyreDetail;
        }
    
        public List<String> getImages() {
            return images;
        }
    
        public void setImages(List<String> images) {
            this.images = images;
        }
    }
    
    • 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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    转换器 CarConvert

    说明:

    • INSTANCE 是MapStruct为我们提供的映射工厂,指定接口类型后自动帮我们创建接口的实现,且保证是线程安全的单例,无需自己手动创建。
    package com.linfanchen.springboot.lab.mapstruct.convert;
    
    import com.linfanchen.springboot.lab.mapstruct.bo.CarBO;
    import com.linfanchen.springboot.lab.mapstruct.bo.CarDetailBO;
    import com.linfanchen.springboot.lab.mapstruct.domain.CarDO;
    import org.apache.commons.lang3.StringUtils;
    import org.mapstruct.Mapper;
    import org.mapstruct.Mapping;
    import org.mapstruct.Mappings;
    import org.mapstruct.Named;
    import org.mapstruct.factory.Mappers;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * 转换类
     */
    @Mapper
    public interface CarConvert {
    
        CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);
    
        /**
         * 来源和目标类的直接转换
         */
        CarBO convert(CarDO carDO);
    
        /**
         * 添加字段处理和映射关系后的转换
         */
        @Mappings({
                @Mapping(source = "id", target = "carId"),
                @Mapping(source = "name", target = "carName"),
                @Mapping(source = "brand", target = "carBrand"),
                @Mapping(source = "tyreDO.id", target = "tyreDetail.id"),
                @Mapping(source = "tyreDO.name", target = "tyreDetail.name"),
                @Mapping(source = "tyreDO.size", target = "tyreDetail.size"),
                @Mapping(source = "images", target = "images", qualifiedByName = "convertImagesStrToList")
    
        })
        CarDetailBO convertDetail(CarDO carDO);
    
        @Named("convertImagesStrToList")
        default List<String> convertImagesStrToList(String images) {
            String[] splitArr = org.springframework.util.StringUtils.split(images, ",");
            return new ArrayList<>(Arrays.asList(splitArr));
        }
    
    }
    
    
    • 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

    使用 CarTest

    package com.linfanchen.springboot.lab.mapstruct;
    
    import com.linfanchen.springboot.lab.mapstruct.bo.CarBO;
    import com.linfanchen.springboot.lab.mapstruct.bo.CarDetailBO;
    import com.linfanchen.springboot.lab.mapstruct.convert.CarConvert;
    import com.linfanchen.springboot.lab.mapstruct.domain.CarDO;
    import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CarTest {
    
        @Test
        public void test() {
            // 创建轮胎对象
            TyreDO tyreDO = new TyreDO();
            tyreDO.setId(888);
            tyreDO.setName("米其林245/45R19");
            tyreDO.setSize(19);
    
            // 汽车图片地址,通过半角逗号分隔的http地址
            List<String> imageList = new ArrayList<>();
            imageList.add("https://www.bmw.com.cn/image.1601043751651.jpg");
            imageList.add("https://www.bmw.com.cn/image.1623295725814.jpg");
            imageList.add("https://www.bmw.com.cn/image.1611042489480.jpg");
            String imageStr = imageList.stream().map(String::valueOf).collect(Collectors.joining(","));
    
            // 创建汽车对象
            CarDO carDO = new CarDO();
            carDO.setId(123);
            carDO.setBrand("BMW");
            carDO.setName("宝马530Li行政版");
            carDO.setPrice(540000);
            carDO.setTyreDO(tyreDO);
            carDO.setImages(imageStr);
    
            // 直接的数据拷贝
            CarBO carBO = CarConvert.INSTANCE.convert(carDO);
            System.out.println(carBO.getImages());
            System.out.println(carBO.getBrand());
            System.out.println(carBO.getName());
            System.out.println(carBO.getTyreDO());
    
            // 带数据转换的拷贝
            CarDetailBO carDetailBO = CarConvert.INSTANCE.convertDetail(carDO);
            System.out.println(carDetailBO.getImages());
            System.out.println(carDetailBO.getTyreDetail().getName());
        }
    
    }
    
    
    • 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
    • 58
    • 59
    • 60

    总结

    在需要进行对象的转换的时候,我们可以使用MapStruct进行各种灵活的转换,最终得到我们想要的数据。

    参考文档:

    官方文档

    MapStruct使用指南

  • 相关阅读:
    相机等效焦距
    python 星号(*) 还能这么用
    Ubuntu MongoDB账户密码设置
    AutoLabel(自动标签)
    泛创轻量化5G专网核心网,助力5G行业应用
    Codeforces Round #813 (Div. 2)
    context:component-scan报错
    Nginx的请求时间限制(如周一到周五可以访问)
    二项分布和泊松分布
    第05、WireShark抓包-协议分析
  • 原文地址:https://blog.csdn.net/oschina_41731918/article/details/126089996