benym的知识笔记 benym的知识笔记
🦮首页
  • Java

    • Java-基础
    • Java-集合
    • Java-多线程与并发
    • Java-JVM
    • Java-IO
  • Python

    • Python-基础
    • Python-机器学习
  • Kafka
  • Redis
  • MySQL
  • 分布式事务
  • Spring

    • SpringIOC
    • SpringAOP
🦌设计模式
  • 剑指Offer
  • LeetCode
  • 排序算法
🐧实践
  • Rpamis

    • Utils
    • Exception
    • Security
  • 归档
  • 标签
  • 目录
🦉里程碑
🐷关于
GitHub (opens new window)

benym

惟其艰难,才更显勇毅🍂惟其笃行,才弥足珍贵
🦮首页
  • Java

    • Java-基础
    • Java-集合
    • Java-多线程与并发
    • Java-JVM
    • Java-IO
  • Python

    • Python-基础
    • Python-机器学习
  • Kafka
  • Redis
  • MySQL
  • 分布式事务
  • Spring

    • SpringIOC
    • SpringAOP
🦌设计模式
  • 剑指Offer
  • LeetCode
  • 排序算法
🐧实践
  • Rpamis

    • Utils
    • Exception
    • Security
  • 归档
  • 标签
  • 目录
🦉里程碑
🐷关于
GitHub (opens new window)
  • 站点优化

    • 将hexo自定义域名升级https
    • hexo到Typecho的迁移日志
  • 思考与方案

    • 海量数据TopK问题
    • 关于DO,VO,DTO,QueryParam的思考
      • 关于DO,VO,DTO,QueryParam的思考
        • 实际例子
        • POJO类设计
        • Controller
        • 类型转换
        • Service层
        • Dao层
        • Mapper层
        • 数据返回
        • 总结
    • 异步消息通知—异步改造
    • 二叉搜索树及AVL树详解
    • 简单高效的代码优化-事务后异步处理
    • 接口管理平台Yapi-最佳实践
    • Yapi私有化部署方案
    • Sentinel-Dashboard持久化生产环境解决方案
    • 单测覆盖率工具在多模块项目中的集成
    • DSTransactional与Transactional事务混用死锁场景分析
  • AI人工智能

    • 基于Docker如何快速部署自己的ChatGPT
  • 实用代码

    • 编程式事务工具类
    • EasyExcel工具类
    • 本地锁工具类
    • Jackson基本配置类
    • Mybatis-plus基本配置类
    • RestTemplate基本配置类
    • 线程池基本配置类
    • RedisTemplate基本配置类
    • SpringData-Mongo基本配置类
    • SpringCache基本配置类
  • 实践
  • 思考与方案
benym
2021-08-10
目录

关于DO,VO,DTO,QueryParam的思考

# 关于DO,VO,DTO,QueryParam的思考

总结一下最近项目中的一些问题

DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。

在项目中Do的作用域用于真正操作数据库的Dao层实现类中。

VO(View Object):视图对象,用于前端展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来

在项目中涉及到-----新增、删除、修改等操作时,作为后端Controller接口的入参对象。当针对的查询语句时,可以将查询的VO对象单独定义一个,用QueryParam作为查询对象,与基本的VO区别开来

DTO(Data Transfer Object):数据传输对象,主要用于外部接口参数传递封装,接口与接口进行传递使用

在项目中接口和接口间常常需要获取大量参数,DTO就是将这些参数封装成为一个对象,简化参数的直接传递

# 实际例子

下面用一个实际的例子展示上述几个对象在具体的开发中的作用域

本文的项目结构为如下

以一个简单的数据库为例,数据库中包含id、name、address、ctime、state五种字段,分别表示用户的id,名字,地址,数据创建事件,状态。

# POJO类设计

与之对应的DO、DTO、VO、QueryParam如下

DO:设计上需要包含所有数据库字段

package com.test.understand.pojo.domain;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import lombok.Data;

@Data
@TableName("test")
public class TestDataDO {
    @TableId
    private Integer id;

    @TableField("name")
    private String name;

    @TableField("address")
    private String location;

    @TableField(value = "ctime",fill = FieldFill.INSERT)
    private Date creatTime;

    @TableField("state")
    private Byte state;
}
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
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

DTO:用于接口间的传输,可以不同于DO传递接口间需要的参数,本文DTO和DO一致

package com.test.understand.pojo.dto;
import java.util.Date;
import lombok.Data;

@Data
public class TestDataDTO {

    private Integer id;

    private String name;

    private String location;

    private Date creatTime;

    private Byte state;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

VO:用于页面展示,不同于DO,有些数据库字段是不必要展示的,VO可以抛弃这些字段,如本文中的id或ctime等

package com.test.understand.pojo.vo;

import lombok.Data;

@Data
public class TestDataVO {
    private String name;

    private String location;

    private Byte state;
}
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12

QueryParam:为了查询参数专门封装的类对象,可包含查询相关字段

package com.test.understand.pojo.query;

import lombok.Data;

@Data
public class TestDataQueryParam {
    
    private Integer id; 
    
    private String name;

    private String location;

    private Byte state;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Controller

以最简单的增删改查为例。我们规定前端传输为JSON,对于增加、修改和删除来说,入参统一接收为VO对象。对于查询操作,我们规定入参统一为QueryParam对象。如下图红框所示:

# 类型转换

首先讲解saveOrUpdate方法和deleteTestData方法。

在这两个方法中,VO对象进入到Controller之后需要转化为DTO对象,因为后续他将经过Service-->ServiceImpl-->Dao-->DaoImpl,即接口之间的传输,其作用域在Controller进入之后到Mapper操作数据库之前。

转化的过程也很简单,可以利用spring提供的BeanUtils.copyProperites快速的将VO中的属性赋值给DTO对象,避免一堆set方法赋值的麻烦。

saveOrUpdate方法:

deleteTestData方法:

对于getTestDataLocation方法其入参QueryParam进入Controller之后无需转换,因为其包含查询字段,可直接通过Service-->ServiceImpl-->Dao-->DaoImpl传递。其作用域在Controller进入之后到Mapper操作完数据库之后的整个阶段。

getTestDataLocation方法:

# Service层

在service和serviceImpl层中,对DTO对象和QueryParam对象无需做对象类型转化

# Dao层

在Dao和DaoImpl的入参定义中,DTO和QueryParam统一不需要转换对象,因为还是接口之间的参数传递,但在DaoImpl中,操作数据库之前,需要将DTO对象转化为DO对象,而QueryParam可以选择用QueryWapper等包装类或者直接传输的方式交给Mapper操作。如下图红框所示

# Mapper层

mapper层用于真正操作数据库,这里采用Mybatis-plus中的BaseMapper提供的接口实现增删改,查询则通过Location查数据,重写一下对应的mapper.xml文件的sql即可

# 数据返回

增加删除修改等操作,前端往往只需要判断操作成功没有即可,所以返回值一般不是一个对象,对于非对象的传输可以直接返回。另外如查询操作,一般会涉及到分页,查出来的数据是List形式展现而从数据库查到的是DO对象,当这种操作返回值时会从Mapper-->Dao-->Service-->Controller一层一层返回回去,这时候就又变成了接口之间的参数传输了,DO对象显然不适合,所以还需转化为DTO对象。如下图红框操作所示,从DO的list转化为DTO的list作为返回值列表。

在返回值到达Controller之后,由于需要展示给前端,DTO对象还需要转化为VO对象

# 总结

  1. 除QueryParam以外,VO对象进入Controller之后需要进行对象转换变为DTO方便数据在接口中间的传递
  2. 在数据库操作之前,DTO对象需要转换为DO
  3. 在返回值的过程中,数据库返回的对象除基本类型之外需要转为DTO传递
  4. 在返回值回到Controller时,需要将DTO对象转换为VO对象,从而返回给前端
编辑 (opens new window)
#SpringBoot#Java
上次更新: 2023/04/15, 21:55:44
海量数据TopK问题
异步消息通知—异步改造

← 海量数据TopK问题 异步消息通知—异步改造→

最近更新
01
SpringCache基本配置类
05-16
02
DSTransactional与Transactional事务混用死锁场景分析
03-04
03
Rpamis-security-原理解析
12-13
更多文章>
Theme by Vdoing | Copyright © 2018-2024 benym | MIT License
 |   |   | 
渝ICP备18012574号 | 渝公网安备50010902502537号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式