• MapStruct代码生成器实现对象转换


    MapStruct对象转换

    1. 数据传输对象

    在商户注册开发过程中用于数据传输的对象有MerchantRegisterVO、MerchantDTO、entity(实体类),它们的用途如下:

    1、MerchantRegisterVO用于应用层接收前端请求及响应前端数据。

    2、MerchantDTO 用于服务层传入及响应数据。

    3、entity(POJO实体类) 用于持久层传入及响应数据。

    三者的关系如下图所示:

    image-20220720202157773

    知识补充:

    VO(Value Object)值对象,通常用于业务层之间的数据传递,和 PO 一样也是仅仅包含数据而已,但 VO应该是抽象出的业务对象,可以和表对应,也可以不对应,这根据业务的需要。
    DTO(Data TransferObject)数据传输对象是系统在交互过程中根据需要及规范将数据封装到数据对象中进行传输。
    DAO(Data AccessObject)数据访问对象,它是一个面向对象的数据库接口,负责持久层的操作,为业务层提供接口,主要用来封装对数据库的访问,常见操作无外乎CURD。

    更多详细对象的介绍可以参考我的另一篇博客:https://blog.csdn.net/weixin_45525272/article/details/123438712

    本项目数据传输对象的规范:

    1、应用层 :如没有接口参数的特殊要求,应用层使用DTO结尾的对象传输,否则单独定义VO结尾的对象传输。

    2、服务层 :统一使用DTO结尾的对象传输。

    3、持久层 :统一使用Entity对象传输。

    2. MapStruct

    2.1 问题:数据传输对象转换的繁琐

    传统的代码编写方式为每层有自己的数据传输对象,当数据流程到该层由需要将数据转成符合要求的格式

    比如:当数据由应用层流转到服务层则需要将数据转成DTO格式,当数据由服务层流向持久层则需要将数据转成Entity格式数据

    下边的代码数据由服务层流向持久层:

        public MerchantDTO createMerchant(MerchantDTO merchantDTO) {
            Merchant entity = new Merchant();
    		//设置审核状态0‐未申请,1‐已申请待审核,2‐审核通过,3‐审核拒绝
            entity.setAuditStatus("0");
    		//设置联系人 
    		entity.setUsername(merchantDTO.getUsername());
    		//设置手机号
            entity.setMobile(merchantDTO.getMobile());
    		//...
    		//保存商户信息
            merchantMapper.insert(entity);
    		//将新增商户的id回写到merchantDTO
            merchantDTO.setId(entity.getId());
            return merchantDTO;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上边代码的问题是:由merchantDTO转成entity实现过程繁琐

    2.2 MapStruct解决数据传输对象转换的繁琐

    MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean对象之间的映射转换的实现。

    MapStruct 使用简单的方法即可完成对象之间的转换,它速度快、类型安全且易于理解。

    官方网址:https://mapstruct.org/

    2.2.1 实现步骤如下:

    1)添加依赖

    在使用MapStruct的工程添加MapStruct依赖:

    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstruct-jdk8artifactId>
    dependency>
    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstruct-processorartifactId>
        <version>1.3.0.Finalversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2)服务层对象转换

    在商户服务工程定义商户对象转换类

    定义MerchantConvert转换类,使用@Mapper注解快速实现对象转换

    import com.shanjupay.merchant.api.dto.MerchantDTO;
    import com.shanjupay.merchant.entity.Merchant;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /*
     * 定义dto和entity之间的转换规则
     * Created by Administrator.
     */
    @Mapper //对象属性的映射
    public interface MerchantConvert {
    
        //转换类实例
        MerchantConvert INSTANCE = Mappers.getMapper(MerchantConvert.class);
    
        //把dto转换成entity
        Merchant dto2entity(MerchantDTO merchantDTO);
    
        //把entity转换成dto
        MerchantDTO entity2dto(Merchant merchant);
    
        //list之间也可以转换,很entity的List转成MerchantDTO list
        List<MerchantDTO> entityList2dtoList(List<Merchant> merchants);
    }
    
    
    • 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

    我在MerchantCovert中定义测试方法测试一下:

    public static void main(String[] args) {
        //将entity转成dto
        Merchant merchant  =new Merchant();
        merchant.setUsername("测试哈哈哈哈哈哈");
        merchant.setMobile("123456");
        MerchantDTO merchantDTO = MerchantConvert.INSTANCE.entity2dto(merchant);
        System.out.println(merchantDTO);
        //将dto转成entity
        merchantDTO.setMerchantName("商户名称");
        Merchant merchant1 = MerchantConvert.INSTANCE.dto2entity(merchantDTO);
        System.out.println(merchant1);
        //定义的list
        List entityList = new ArrayList();
        entityList.add(merchant);
        //将lIST转成包含dto的list
        List list = MerchantConvert.INSTANCE.entityList2dtoList(entityList);
        System.out.println(list);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行结果如下:

    image-20220720203342129

    2.3 应用层对象转换

    实现步骤与上述基本相同

    在商户平台应用工程定义商户对象转换类

    import com.shanjupay.merchant.api.dto.MerchantDTO;
    import com.shanjupay.merchant.vo.MerchantRegisterVO;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    /*
     * 将商户注册vo和dto进行转换
     * Created by Administrator.
     */
    @Mapper
    public interface MerchantRegisterConvert {
    
        MerchantRegisterConvert INSTANCE = Mappers.getMapper(MerchantRegisterConvert.class);
    
        //将dto转成vo
        MerchantRegisterVO dto2vo(MerchantDTO merchantDTO);
        //将vo转成dto
        MerchantDTO vo2dto(MerchantRegisterVO merchantRegisterVO);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    我在MerchantRegisterConvert中定义测试方法测试一下:

    public static void main(String[] args) {
        MerchantRegisterVO merchantRegisterVO = new MerchantRegisterVO();
        merchantRegisterVO.setMobile("123456789");
        merchantRegisterVO.setUsername("哈哈哈哈哈哈哈");
        MerchantDTO merchantDTO = MerchantRegisterConvert.INSTANCE.vo2dto(merchantRegisterVO);
        System.out.println(merchantDTO.toString());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果如下:

    image-20220720203723068

    3. 代码优化

    1、优化服务层代码

    修改商户服务工程MerchantServiceImpl中的createMerchant方法

    public MerchantDTO createMerchant(MerchantDTO merchantDTO) {
        //将dto转成entity
        Merchant entity = MerchantConvert.INSTANCE.dto2entity(merchantDTO);
        //设置审核状态0‐未申请,1‐已申请待审核,2‐审核通过,3‐审核拒绝
        entity.setAuditStatus("0");
        //保存商户信息
        merchantMapper.insert(entity);
        //将entity转成 dto
        MerchantDTO merchantDTONew = MerchantConvert.INSTANCE.entity2dto(entity);
        return merchantDTONew;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、代码应用层代码

    修改商户平台应用工程MerchantController中的registerMerchant方法

    @ApiOperation("商户注册")
    @ApiImplicitParam(value = "商户注册信息",name = "merchantRegisterVO",required = true,dataType = "MerchantReg
    @PostMapping("/merchants/register")
    public MerchantRegisterVO registerMerchant(@RequestBody MerchantRegisterVO merchantRegisterVO){
        //校验验证码
        smsService.checkVerifiyCode(merchantRegisterVO.getVerifiykey(),merchantRegisterVO.getVerifiyCode()
        //使用MapStruct转换对象
        MerchantDTO merchantDTO = MerchantRegisterConvert.INSTANCE.vo2dto(merchantRegisterVO);
        merchantService.createMerchant(merchantDTO);
        return merchantRegisterVO;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    硬核,你见过机器人玩“密室逃脱”吗?(附代码)
    8 个无需编写代码即可使用 Python 内置库的方法
    Vue2.0开发之——Vue基础用法-列表渲染指令(24)
    Elasticsearch节点、副本、分片规划
    OpenHarmony4.0对RK3566的烧写过程
    WebSocket--技术文档--架构体系--《WebSocket实现原理以及关键组件》
    代码随想录算法训练营day35 | 0-1背包理论基础、416. 分割等和子集
    小程序源码:多功能喝酒神器
    Docker容器的数据卷
    使 DAO 保持粘性的四个因素
  • 原文地址:https://blog.csdn.net/weixin_45525272/article/details/125900315