假如有一张user表,里面有几个字段:

user表
user_id user_name pass_word create_time dept_id

假设就这么多吧,一张很基础的表,那么对应Java的写法就是一个类:

class User{
private Long userId;
private String userName;
private String passWord;
private LocalDateTime createTime;
private Long deptId;
//getter setter constrcutor.....【可以用lombok,随意,我这里就省略了】
}

那么我现在需要对于User这张表进行增删改查,那么如果我假设你学过Mybatis?还是JPA这种持久层框架的话,或者你只要学过JDBC的话,你就应该知道,Java中肯定需要一个对象来映射数据库的这张表。User类的每个属性就是数据库表的每一个字段,该类的每一个对象就代表数据库中的每一行,List就代表该表的所有记录。

这个User类就被称为PO,一般也不会加PO的说法,这个类一般就是User。


下面来说说DTO和VO。Data Transfer Object和View Object(不知道拼错没有?大概就这个意思)下面用一个实际场景解释一下:

比如,User这张表,一般在前端我们会进行分页+条件查询,然后在前端用一个列表组件,对于后端请求过来的数据做渲染。对于CRUD来说,这也是一个基本的需求。

那么假设现在有这样一个情况:假设我们再简化一下情况,我们只做条件查询,我需要按照用户名userName模糊匹配,用户创建时间createTime区间匹配的时候,我后端应该如何写?

或者换言之,我后端应该用一个什么对象来接收前端传过来的请求参数?

这时候我们来想想,User类对象,他还能胜任吗?userName还好说,那create Time的区间怎么表示呢?

显然这时候我们就不能在后端这样写了:

public XXX【返回值】 selectUserByCondidition(@RequestBody @Validated User user);

光靠一个User对象我们是不足以接收前端传过来的请求参数的,那你说我可以这样啊:

public XXX【返回值】 selectUserByCondidition(String userName,
LocalDateTime startTime,
LocalDateTime endTime)

。。。。。

这还只是两个字段的条件,如果字段一但多起来了,你确定这样写?你确定老板看了以后不会让你当场毕业?

。。。。。

所以这时候我们就要用到DTO了,数据传输对象,用于在网络中涉及到数据传输的封装对象。那么此时我们就可以在后端定义这样一个DTO:UserQueryConditionDTO【用户条件查询DTO】

public class UserQueryConditionDTO{
private String userName;
private LocalDateTime startTime;
private LocalDateTime endTime;
//getter setter validation_annotation constrcutor【这些答主就不写了】 ....
}

然后我们后端接口就可以这样写:

public XXX【返回值】 selectUserByCondidition(@RequestBody @Validated UserQueryConditionDTO dto);

简单明了,别人一看代码,点进去一看,你再给字段打上备注,一下就清晰了。这就是DTO的用处。

下面来说VO的用处:VO意思就是View Object,View这个单词学过MVC思想的都知道,【都能看到这个问题了,不会还有人MVC都不知道吧】,叫视图层,那么View Object呢?顾名思义,那就是返回给视图层【前端】需要用到的对象。

这时候又有人不懂了,返回给前端我需要啥VO啊,什么意思?还是用这个User举例子。

我通过刚才的DTO,然后通过一系列JDBC操作,我查询到了List列表,里面就包含每一个用户的完整信息【用户Id,用户名,密码,部门Id,创建时间】,也就是上面表的五个字段。

但是你准备就把这个List返给前端吗??前端展示的用户所属部门,至少是展示部门名吧?怎么可能直接在前端列表去展示每个用户的所属部门Id呢?

不会吧,不会真有兄弟给前端说,你获取到List这个数组以后,你对于每一个dept_Id再分别发请求,我给一个接口,你给我dept_Id,我给你返回dept_Name,不就完了吗。你确定前端兄弟不想打屎你?这样的网络IO有考虑过吗,数据量多了一个页面都是几十个请求到时候,这样是肯定不行的。

那部门名去哪里找呢?那肯定有一张部门表咯,这不就是表的关联关系吗,一般来说,最简单的情况下,都是通过Id关联,假设有一张部门表dept:

dept表
Id dept_name create_time deleted

Id就是部门的Id,和User表的dept_id有映射关系,deleted就是逻辑删除,create_time和dept_name就不多说了。逻辑删除不懂的请自行百度或谷歌。

大概提一下,逻辑删除就是当前端删除该数据的时候,用这个标识字段来表示该数据的删除情况,假设0就是未删除,1就是已删除。在任意查询的时候我们也会避开逻辑删除字段为1的数据。

那么此时,我们就应该用关联来查询出用户的所属部门名了:SQL伪代码,看懂意思就行

select u表的所有数据,d.dept_name
from user u
left join dept d
on u.dept_id = d.Id//后面你排不排序啥的我也不管了,这里自行按照业务逻辑添加

那么此时,我们通过该SQL返回的数据还能用User对象接收吗?

当然就不行了,因为User对象没有DeptName这个属性,但现在我们需要一个对象封装带有deptName属性的user。

那么我们考虑该对象是需要发送给前端来展示的,也就是视图层,所以我们就需要一个对象,来传输给视图层,那么,就是我们的VO了。UserVO来返回给前端。

class UserVO{Long userId;String userName;String deptName;String password;Long deptId;LocalDateTime createTime;
//Getter  Setter etc ...
}

这就是VO的用处


下面来说一下DAO,DAO一般在刚学MVC的时候会涉及到,Data Access Object,数据访问对象,他就是用来访问数据库的对象,我们一般就会在这里面写上很多查询数据库的方法。

比如UserDAO【User的CRUD操作】,一般增删改查会有五个方法:

  1. 条件分页查询
  2. 按照批量Id【也可以传单个】删除
  3. 新增
  4. 按照Id查询某一条的数据【修改时候数据前端回显】
  5. 修改接口
interface/class UserDAO {public List<UserVO> queryUserByCondition(UserDTO dto,PageCondition page);public User getUserById(Long userId);public int deletedUserByBatchIds(List<Long> userIds);public int editUser(UserEditDTO dto);public int addUser(UserAddDTO dto);}

如果看到这里都没问题,那么有些靓仔可能又有问题了,你这UserDAO为啥类型又写interface又写class啊?

这个其实是接口的一种思想,如果你把查询数据库的代码【假如是JDBC逻辑,不用持久层框架哈】,那么这个UserDAO会变得很大,如果别人想来看一下你这个UserDAO里面到底有什么方法的时候,别人就会看着很头疼。

所以我们一般把UserDAO写成一个接口,里面定义UserDAO操作数据库的方法的规范,然后会有一个类UserDAOImpl去实现UserDAO接口,然后在Impl类中写上真正操作数据库的代码。这样别人想了解UserDAO到底提供了哪些功能的时候,可以,看接口即可。想看功能到底怎么实现的时候,也可以,看Impl实现类的业务逻辑即可。

DAO其实就是用来操作数据库的,封装所有对于数据库的数据CRUD操作,然后让业务层直接注入DAO对象,然后使用该方法即可。

不过在后面,我们更倾向于把DAO对象叫做Mapper【Map不是地图的意思,在后面开发中他更多的意思在于映射】,以后就不叫UserDAO了,我们一般叫UserMapper【mapper的意思和dao一样】,UserMapper就是表示用于封装数据库操作的一个映射对象,可以这样理解吧,不过mapper的意思和DAO八九不离十,后面开发中就是一个概念了。【下文中就把DAO称为Mapper了

那么这时候又有靓仔想问了,假如我有很多表,User,Dept,SysJob【系统任务表】,SysLog【系统日志表】,SysDict【系统字典表】等等很多表,每一张表我都想提供基本的CRUD功能。

那么我难道要把上面五个逻辑几乎一样的CRUD方法还要在每一个XXXMapper中写一次吗?

比如UserMapper,DeptMapper,SysJobMapper,SysLogMapper,SysDictMapper,我每一个Mapper都要去写通用的五个CRUD逻辑吗?显然是太冗余了,那我能不能抽出一个公用的BaseMapper,来封装单表的CRUD操作呢?

如果上面思路能懂,那你学MybatisPlus也就不难了,MybatisPlus【简称MP】,就是提供了一个Base Mapper接口,这个接口里面封装了大量的单表CRUD便利操作,相当于以后,我们只需要这样写:

public interface UserMapper extends BaseMapper<User>

我们就可以在Mapper层写0代码,直接快速完成对于user单表的CRUD了,包括单表的各种复杂查询,直接0SQL开发【就是不用写一句SQL】,快不快?


BO就是Business Object了,业务对象,这个就不用怎么解释了,就是封装了业务逻辑的对象,一般开发中,BO估计就是代指Service层吧?业务层对象,MVC的设计模式一般是前端请求,来到后端的Controller【Provider】控制器层,控制器做一些最基本的校验【比如身份校验,入参校验,日志AOP等等】,然后分发请求到相应的业务层【也就是Service组件】来做处理。

业务层对于请求进行业务处理,如果要涉及到和数据库交互的,就是用Mapper【也就是DAO】层对象和数据库交互即可,大概就是这样一个逻辑。按照这样来说,Service层对象,比如User Service,应该算BO对象吧,这一点答主不是特别清楚,参见评论区坐等大神解惑。


POJO就是Plain And Ordinary Java Object,简单Java对象,这就没啥 好讲的。

DO,Data Object,数据对象,这概念吧,其实有是有,但是用的,我个人感觉不多,有一种情况就是微服务之间互相传输对象数据的时候,我们就会将该数据抽取出来。

比如商品下单以后,大量的JSON数据会传输到后台,我们会在后台调用很多模块,比如OMS/订单管理模块,又或是ERP模块,又或是WMS/库存物流模块,等等等等,会调用很多其他微服务模块。不同服务之间传输对象,要不然就将对象定义为DO【或者TO,不同叫法而已,Transfer Object或者Data Object】,然后两个模块之间RPC调用,传输的对象要被两个模块共享,要不然就将每一个模块涉及的各种实体对象单独抽出来放在一个entities模块下啊,要不然就是将这些微服务模块之间的交互传输对象定义在Common模块中,作为DO或者TO,来进行微服务之间的数据传输所用。

PO BO VO DTO POJO DAO DO相关推荐

  1. Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分

    Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分 PO:持久对象 (persistent object),po(persiste ...

  2. PO BO VO DTO POJO DAO概念及其作用(附转换图)

    J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了(听过老罗对这种现象的批判的朋 ...

  3. PO/BO/VO/DTO/POJO/DAO/DO

    文章目录 DO(Domain Object) DO(Data Object) PO VO BO DTO POJO DAO JavaBean EJB Entity 应用程序的分层设计 MVC 业务分层 ...

  4. java常见业务对象_Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分...

    PO:持久对象 (persistent object),po(persistent object)就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数 ...

  5. PO BO VO DTO POJO DAO DO 在java中的概念

    PO BO DTO VO POJO PO DTO VO BO 都叫POJO,就是个简单的java对象: DAO 是进行数据库增删改查的类. BO 业务对象,封装对象.复杂对象 ,里面可能包含多个类: ...

  6. PO BO VO DTO POJO DAO概念

    刚开始写blog,主要的目的是积累,学习,供日后查找! 如题,今天跟主管交流,被好多名词整蒙了,这些词以前都听说过,但是对其内在的含义并不是很清楚的了解,借此机会写上来,增加记忆和理解吧. 一下是原文 ...

  7. PO BO VO DTO POJO DAO DO概念解读

    假如有一张user表,里面有几个字段: user_id user_name pass_word create_time dept_id 假设就这么多吧,一张很基础的表,那么对应Java的写法就是一个类 ...

  8. java中bean对象_JAVA中PO,BO,VO,DTO,POJO,Entity,JavaBean,JavaBeans各个对象的区别,以及lombo、jpa简介及用法...

    常见JAVA类概念介绍 PO:持久对象 (persistent object). 是ORM(Objevt Relational Mapping)框架中Entity,PO属性和数据库中表的字段形成一一对 ...

  9. JAVA中PO,BO,VO,DTO,POJO,Entity

    https://my.oschina.net/liaodo/blog/2988512 转载于:https://www.cnblogs.com/dianzan/p/11311217.html

最新文章

  1. Android Opengl
  2. mysql bin log日志
  3. javaee 中文帮助文档_大牛耗时三天整理的:微服务+Nginx+Kubernetes实战文档和面试题...
  4. java中timer和timertask_使用Java中的Timer和TimerTask
  5. centos 卸载docker_Docker (一) 安装
  6. excel中if如何加android,Excel 如何实现函数IF的嵌套超过七层
  7. android apk安装包 华为提示安装包无效或与操作系统不兼容,魅族提示apk仅为测试版,要求下载正式版安装
  8. 博士申请 | 蒙纳士大学(苏州)陈存建老师招收人工智能方向全奖博士生
  9. input file选择图片后显示(FileReader)
  10. Python自动化办公【PDF文件自动化】
  11. 软件测试交行项目的流程,交通银行流程引擎POC测试报告——IntelliFlow.pdf
  12. TCP连接大量CLOSE_WAIT状态问题排查
  13. 运算放大器的16个基础知识点
  14. Liunx中shell命令行和权限的理解
  15. ALEXA站长全攻略(转)
  16. 高德地图红绿灯读秒是怎么实现的?(二)
  17. MyBatis 01 快速入门
  18. 安装指定版本的Mariadb数据库
  19. Windows下使用任务计划程序实现宽带开机自动拨号和断线自动重连
  20. 风雷影音v2.1.1.0落雪梨花绿色精简版【首家独创双播放内核架构、全面支持高清格式】...

热门文章

  1. 顺序容器(C++ Primer 5th)
  2. learning python_Python学习手册 第5版(Learning Python, 5th Edition)[鲁特兹] PDF影印版[13MB]...
  3. 2、Linux的常见发行版、开源协议、目录结构及哲学思想
  4. 使用ado连接orical数据库
  5. 抖音seo账号矩阵新玩法?应该如何借助新的接口技术开发
  6. Python在照片上添加水印的方法
  7. Python中的PIL库处理图片实例(个人笔记)
  8. Atmega48,168,328P等芯片的差别在哪,后缀含义
  9. 使用pig对钓鱼网站链接url做词频统计【大数据处理与分析技术】
  10. jpg转换成pdf转换器中文版推荐