POJO/DTO/DO/EO/VO/BO/PO/AO的含义和使用_dto vo eo-程序员宅基地

技术标签: pojo  Java基础/JUC/JVM  dto  

关于POJO/DTO/DO/EO/VO/BO/PO/AO

本文讨论 POJO/DTO/DO/EO/VO/BO/PO/AO 的定义,另外讨论了这些xO在controller、service、dao/mapper层里的使用规范。另外还稍微讨论了controller中是否要 “轻逻辑”,mapper接口的规范等等问题。

前言

在我们的java项目中存在各种xO的概念,如POJO/DTO/DO/EO/VO,还有些后端开发可能不太常见的BO/PO/AO。这里结合阿里Java手册以及其他博客的知识总结一下。这些xO一般都具有简单的结构,如setter/getter/toString

  • POJO:Plain Old/Ordinary Java Object,是其他xO的统称。笔者也喜欢用bean来统称这些xO,但后来觉得不准确,因为bean一般指spring容器所管理的bean
  • DTO:Data Transfer Object,用来作为Controller的出参和Service的出参。一般分为两类:Controller的入参叫xxxReqDTO,Service层的出参叫xxxRespDTO。也有很多系统并不分得这么细。
  • DO:Data Object,用来和单表一一对应的实体类。也有资料显示DO是Domain Object(域对象),
    • EO:Entity Object,实体对象。有些公司用来表示跟表一一对应的类,即相当于DO。
    • PO:记得最初的阿里Java文档定义为Persistence Object,持久化对象,当时文档说是跟表一一对应的,不知道后来的文档为什么改成了DO(难道记错了?)
  • VO:View Object,阿里Java文档中说用来跟前端页面一一对应的对象。偶尔会有用错的情形,比如用来作为Controller层的入参
  • BO:Business Object,阿里Java文档说明由 Service 层输出的封装业务逻辑的对象。不理解
  • AO:Application Object,应用对象,不知道什么用。

其实搞这么多xO,有时候真的会影响效率,尤其非大型公司需要快。

【阿里Java手册】
POJO(Plain Ordinary Java Object): 在本手册中,POJO 专指只有 setter/getter/toString 的简单类,包括 DO/DTO/BO/VO 等。
DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。
AO(Application Object):应用对象,在 Web 层与 Service 层之间抽象的复用对象模型,极为贴 近展示层,复用度不高。
VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。

总结:这么多O,都搞晕了,感觉常用的就只有DTO;和表一一对应的类要不要后缀都不是很重要,所以DO也不是说很常用(当然有更好,能快速识别)

xO 的使用方法

总结:controller入参用dto,出参也是dto(从service层返回的);service层入参是dto,出参dto;dao层入参不建议用dto而是分拆,出参dto或do。dao层接口不要用map作为入参,有不用map和list作为出参。

  • http(s) 传参的方式

    常见如下

    • 键值对:Content-Type 是 x-www-form-urlencoded 。准确说是 “名值对”,因为是可以重复的,如 ?favor=music&favor=reading 中的favor。

      特殊情况

      • 键值对传文件:Content-Type 是 form-data。跟 “键值对” 不同之处是可传文件
    • 传 JSON:Content-Type 是 application/json。注意和 “传JSON字串” 的表述区分开,后者是键值对的传参方式 ?jsonStr={}

    • 路径参数:如 /user/9527,中的 9527 是路径参数

  • Controller 入参

    • 参数少:采用 “键值对” 和 “路径参数”
    • 参数多、结构复杂:采用 “传JSON”。一般用 xxxReqDTO 接收
      • 注意:有时不区分这么细,将 xxxReqDTO 和 xxxRespDTO 合并用同一个,叫 xxxDTO
      • “传JSON” 的同时也可以使用键值对方式。即JSON字串在请求方法体里,键值对参数追加在URL
  • Controller 出参

    • 出参格式
      • 一般总是返回200的 http 状态码,并用固定的返回类封装起来,例如 ResponseDTO
      • ResponseDTO 一般带有系统自定义的业务异常码、信息提示、时间、数据
    • 出参从 Service 层获得,一般不再二次处理,直接放在 ResponseDTO 的 “数据” 里。
    • 无出参用 ResponseDTO
  • Service 层的入参

    • 接收Controller层传入的简单类型或者 xxxReqDTO(或 xxxDTO)
  • Service 层的出参

    • 出参简单的,直接返回:如基本类型、包装类和String等

    • 出参复杂的,返回 xxxRespDTO(或 xxxDTO)

      • 注意:“返回 xxxRespDTO” 的表述也包括 List、PageInfo、Map<String, xxxRespDTO>等形式,下文不再赘述
    • 反例:

      • 【禁止】有时贪快,用DO 作为出参,是不好的实践,必须用 DTO
      • 【疑惑】是不是每个Service接口都要定义自己的 DTO,DTO 可以跨不同的 Service 接口复用吗? 这个真的很纠结,复制一份DTO比较独立但是代码却重复非常多,用继承又导致复杂化不直观
  • Dao 层(Mapper)的入参

    • 简单和复杂的参数都分拆成基本类型、包装列和String等
      • insert接口或update接口会有很多字段,全列出来会不会很麻烦? 这些接口的sql不太可能自己写,因为代码生成框架可以自动生成的,所以不麻烦
      • 【建议】建议别用 Service 层的 xxxReqDTO(或 xxxDTO)作为入参,因为通常并非DTO里的所有字段在sql里会用到
      • 【疑惑】其实这个还是有点纠结的,要不要定义一个 xxxQuery 作为 mapper的查询入参?
    • 反例:
      • 【禁止】禁止入参用 Map
      • 【建议】建议入参也别用 xxxDO,因为xxxDO势必有很多字段其实并不是sql里需要的
  • Dao 层(Mapper)的出参

    • 简单的直接返回
    • 复杂的返回 xxxRespDTO(或xxxDTO)
      • 【建议】能不能用 xxxDO 作为mapper的出参? 这块不强制禁止,因为生成的sql就是返回这些的
    • 反例:禁止出参用 Map 或 List

其他思考

  • controller层:对此层大家的共识是不要写重的逻辑。但是要轻逻辑到什么程度? 比如我比较喜欢的一种方式是接口参数校验在参数声明中进行,但controller的方法的大括号里仅仅有一行调用service层的代码。这种方式把参数的进一步校验也交给service了。其实这种做法虽然很简洁,但是可能很难复用service层的接口。所以,是不是可以保证controller层有轻的 “分发” 性质的代码? 例如一个接口既可以新增也可以修改,在controller层里判断operType,新增的话分发到新增的service接口里,修改的话分发到修改的service接口里。
  • controller里的RequestMapping,一般可能叫 “路由”、“路由地址”,这可能是来源于前端router的概念;其实也可以叫endpoint(端点),这个称呼更加显得后端
  • 其实我不太建议用 “路径参数”,会容易混淆
@GetMapping("/user/list")
public List<ListUserDTO> listUser(String name) {
    }@GetMapping("/user/{name}")
public List<ListUserDTO> listUser2(@PathVariable("name") String name) {
    }
  
会符合 "精确匹配优先" 的原则,即访问/user/list匹配上面的,假设有个name是 "list" 值的,就没办法调用到下面的方法;如果是非 "list",则匹配下面的方法。

------------------------------

@GetMapping("/user/{name}")
public List<ListUserDTO> listUser2(@PathVariable("name") String name){
    }

@GetMapping("/user/{id}")
public QueryUserDTO queryUser(@PathVariable("id") Integer id){
    }

这两个方法能正常启动springboot,但是只有在运行时抛出异常,即无法确认要匹配哪个方法。因为前端的传参本质上是没有字串和整形的区分的,本质都是字串,只是在spring框架里如需要会进行转换。

* dao层的mapper接口真的不建议使用pojo作为入参,强烈建议把字段分拆成基本类型、包装类和String即可。原因是:1、这样清晰一点;2、一般入参的个数不会很多,比较多入参的insert接口都交给了代码生成,完全不需要自己写这样的sql。3、pojo作为入参,比如这个pojo是service层传如的xxxReqDTO,但是这个dto里并非所有字段都是sql里的条件,所以这会造成不好维护。
* dao层的mapper更加不建议用map作为入参,看似灵活,实际过于灵活导致难以分析真正传入的参数
* dao层的mapper接口出参也不建议用Map<String, Object> 或 List<Map<String, Object>>,看似灵活,实际也是过于灵活导致很难维护,比如从map中get值,key写错时很难发现。我们希望在编码的早期阶段尽快暴露出这些bug
* service层的接口是可以调用其他同是service层的接口的。有时候为了共用接口,确实会有这样的需要。那被共用的接口是否要提取到类似CommonService里呢?  我建议是不需要不强制。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w8y56f/article/details/103515185

智能推荐

python色卡识别_用Python帮小姐姐选口红,人人都是李佳琦-程序员宅基地

文章浏览阅读502次。原标题:用Python帮小姐姐选口红,人人都是李佳琦 对于李佳琦,想必知道他的女生要远远多于男生,李佳琦最早由于直播向广大的网友们推荐口红,逐渐走红网络,被大家称作“口红一哥”。不可否认的是,李佳琦的直播能力确实很强,他能够抓住绝大多数人的心理,让大家喜欢看他的直播,看他直播推荐的口红适不适合自己,色号适合什么样子的妆容。为了提升效率,让自己的家人或者女友能够快速的挑选出合适自己妆容的口红色号,今..._获取口红品牌 及色号,色值api

linux awk命令NR详解,linux awk命令详解-程序员宅基地

文章浏览阅读3.6k次。简介awk命令的名称是取自三位创始人Alfred Aho 、Peter Weinberger 和 Brian Kernighan姓名的首字母,awk有自己的程序设计语言,设计简短的程序,读入文件,数据排序,处理数据,生成报表等功能。awk 通常用于文本处理和报表生成,最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。awk 通常以文件的一行为处理单位..._linux awk nr

android 网络连接失败!failed to connect to /192.168.1.186(port 8080)_failed to connect to 192.168.88.218:80-程序员宅基地

文章浏览阅读1.3w次,点赞5次,收藏2次。在网上找了一个小时,一直没有头绪,因为上个星期还是好好的,最后看到一个大神的解答,只需要将防火墙关闭就好了.原本向测试功能的,却卡在了登录上.以此记录.另外好像还有种错误是电脑与手机连接的WiFi不同,也可以看看...._failed to connect to 192.168.88.218:80

matlab 多径衰落,利用MATLAB仿真多径衰落信道.doc-程序员宅基地

文章浏览阅读1.9k次。利用MATLAB仿真多种多径衰落信道摘要:移动信道的多径传播引起的瑞利衰落,时延扩展以及伴随接收过程的多普勒频移使接受信号受到严重的衰落,阴影效应会是接受的的信号过弱而造成通信的中断:在信道中存在噪声和干扰,也会是接收信号失真而造成误码,所以通过仿真找到衰落的原因并采取一些信号处理技术来改善信号接收质量显得很重要,这里利用MATLAB对多径衰落信道的波形做一比较。一,多径衰落信道的特点关于多径衰落..._matlab多径衰落工具箱

python对json的操作及实例解析_import json灰色-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏17次。Json简介:Json,全名 JavaScript Object Notation,是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。(来自百度百科)python关于json文_import json灰色

mysql实现MHA高可用详细步骤_mysql mha超详细教程-程序员宅基地

文章浏览阅读1.1k次,点赞6次,收藏3次。一、工作原理MHA工作原理总结为以下几条:(1) 从宕机崩溃的 master 保存二进制日志事件(binlog events);(2) 识别含有最新更新的 slave ;(3) 应用差异的中继日志(relay log) 到其他 slave ;(4) 应用从 master 保存的二进制日志事件(binlog events);(5) 通过Manager控制器提升一个 slave 为新 m..._mysql mha超详细教程

随便推点

Linux环境下主从搭建心得(高手勿喷)_linux的java主从策略是什么-程序员宅基地

文章浏览阅读194次。一 java环境安装:1 安装JDK 参考链接地址:https://blog.csdn.net/qq_42815754/article/details/82968464注:有网情况下直接 yum 一键安装:yum -y list java(1)首先执行以下命令查看可安装的jdk版本(2)选择自己需要的jdk版本进行安装,比如这里安装1.8,执行以下命令:yum install -y java-1.8.0-openjdk-devel.x86_64(3)安装完之后,查看安装的jdk 版本,输入以下指令_linux的java主从策略是什么

ACM第四题_acm竞赛题 i 'm from mars-程序员宅基地

文章浏览阅读104次。定义int 类型,由while实现A,B的连续输入,输出A+B的值按Ctrl Z结束循环。#include&amp;lt;iostream&amp;gt;using namespace std;int main(){ int A,B; while(cin&amp;gt;&amp;gt;A&amp;gt;&amp;gt;B) { cout&amp;lt;&amp;lt;A+B&amp;lt;&_acm竞赛题 i 'm from mars

TextView.SetLinkMovementMethod后拦截所有点击事件的原因以及解决方法-程序员宅基地

文章浏览阅读5.2k次。在需要给TextView的某句话添加点击事件的时候,我们一般会使用ClickableSpan来进行富文本编辑。与此同时我们还需要配合 textView.setMovementMethod(LinkMovementMethod.getInstance());方法才能使点击处理生效。但与此同时还会有一个问题:如果我们给父布局添加一个点击事件,需要在点击非链接的时候触发(例如RectclerV..._linkmovementmethod

JAVA实现压缩解压文件_java 解压zip-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏31次。JAVA实现压缩解压文件_java 解压zip

JDK8 新特性-Map对key和value分别排序实现_java comparingbykey-程序员宅基地

文章浏览阅读1.3w次,点赞7次,收藏21次。在Java 8 中使用Stream 例子对一个 Map 进行按照keys或者values排序.1. 快速入门 在java 8中按照此步骤对map进行排序.将 Map 转换为 Stream 对其进行排序 Collect and return a new LinkedHashMap (保持顺序)Map result = map.entrySet().stream() .sort..._java comparingbykey

GDKOI2021普及Day1总结-程序员宅基地

文章浏览阅读497次。第一次参加GDKOI,考完感觉还可以,结果发现还是不行,有一些地方细节打错,有些失分严重,总结出以下几点:1.大模拟一定要注意,细节打挂就是没分,像T1就是一道大模拟题,马上切了,后面就没想着检查以下,导致有些地方挂掉了,用民间数据一测,才85分。2.十年OI一场空,不开longlonglong longlonglong见祖宗。今天的T2本来想用暴力水点分的,结果没想到longlong→intlong long\to intlonglong→int,40→040\to040→0。3.代码实现能力太差,_gdkoi

推荐文章

热门文章

相关标签