“POJO JavaBean DO BO DTO VO PO SO”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
→‎DTO
 
(未显示同一用户的83个中间版本)
第1行: 第1行:
=== 参考 ===
+
=== 开篇 ===
https://www.bilibili.com/video/BV18L4y1F7PU
+
PO、VO、DTO 都是含义,
 +
 
 +
当一个对象的属性字段和数据库中某一张表的字段不多不少准确对应,可以通过调用 DAO(Mapper)直接对应进行 CRUD 操作的时候,这个对象就是一个 PO ;
 +
 
 +
当用一个对象来封装 http 请求发送到 Controller 的数据的时候,用它封装 DAO 查询结果数据的时候,这个对象就是一个 DTO;
 +
 
 +
当用一个对象来封装返回给 http 请求调用响应数据的时候,它就是一个 VO。
 +
 
 +
 
 +
如果是一个非常简单的业务,只用一个类就能满足以上三个条件,那么这个类的对象就既是 PO,又是 DTO,同时还是 VO:
 +
 
 +
比如对应这么一张表 student (id, name, age) 有<syntaxhighlight lang="java">
 +
public class Student {
 +
 
 +
    private long id;
 +
 
 +
    private String name;
 +
 
 +
    private Integer age;
 +
 
 +
    public long getId() {
 +
        return id;
 +
    }
 +
 
 +
    public void setId(long id) {
 +
        this.id = id;
 +
    }
 +
 
 +
    public String getName() {
 +
        return name;
 +
    }
 +
 
 +
    public void setName(String name) {
 +
        this.name = name;
 +
    }
 +
 
 +
    public Integer getAge() {
 +
        return age;
 +
    }
 +
 
 +
    public void setAge(Integer age) {
 +
        this.age = age;
 +
    }
 +
}
 +
</syntaxhighlight>这么一个类,
 +
 
 +
在 DAO 里调用 save、update 直接就可以操作表中一条记录的时候,它起到的就是作为一个 PO 的作用;
 +
 
 +
当通过 DAO 查询,用它封装查询结果数据并返回给上层 Servcie 和 在 Controller 层封装请求数据、在 Service 层、对象与对象之间封装参数进行传递的时候,它起到的就是作为一个 DTO 的作用;
 +
 
 +
当封装由 Controller 层影响给 http 请求调用响应数据的时候,它起到的就是作为一个 VO 的作用。
 +
 
 +
无关于一个类是什么样的命名后缀。
 +
 
 +
Student(或命名为 StudentPO)和 StudentDTO、StudentVO 这样命名的多个类存在的意义在于:
 +
 
 +
按照单一职责原则创建的多个类的对象对需求进行解耦,作用在不同的应用场景下、满足不同的需求,使得它们之间不会互相干涉、影响。
 +
 
 +
比如:
 +
 
 +
今天的需求实现需要 http incoming 再多传一个参数了;
 +
 
 +
明天前端调用要求 http 请求 response 需要再多返回一个参数了;
 +
 
 +
后天数据库的表里又多加了一个字段了;
 +
 
 +
如果只使用一个类,就难以准确地满足这些后序的扩展需求,所以才要有 DTO、PO、VO 这样不同的概念。
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
=== 对比 ===
 +
{| class="wikitable"
 +
|+
 +
|
 +
!DTO
 +
!POJO
 +
!VO
 +
|-
 +
!名称
 +
|Data Transfer Object
 +
数据传输对象
 +
|Plain Old Java Object
 +
普通旧 Java 对象
 +
|Value Object
 +
值对象
 +
|-
 +
!相同点
 +
|
 +
|
 +
|
 +
|-
 +
!不同点
 +
|
 +
|
 +
|
 +
|-
 +
!使用场景
 +
|封装 Web 请求传入的值
 +
|
 +
|
 +
|}
 +
{| class="wikitable"
 +
|+
 +
|
 +
!SO
 +
!BO
 +
|-
 +
!名称
 +
|Service Object
 +
 
 +
服务对象
 +
|Business Object
 +
 
 +
业务对象
 +
|-
 +
!使用场景
 +
|作为若干个 BO (单个业务对象)的 facade 提供给 REST controller 调用
 +
|主要封装业务逻辑
 +
|-
 +
!不同点
 +
|供 REST controller 调用;
 +
业务逻辑代码少;
 +
 
 +
直接和 DAO 打交道,包含事务处理;
 +
|供 SO 调用;
 +
业务逻辑代码多;
 +
 
 +
不直接和DAO打交道,不包含事务处理
 +
|-
 +
!相同点
 +
| colspan="2" |都包含业务逻辑代码的实现;
 +
|-
 +
!意义
 +
|事务处理;
 +
隐藏业务逻辑实现;
 +
|封装具体业务逻辑实现的细节
 +
|}
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
=== DTO ===
 +
https://www.baeldung.com/java-pojo-javabeans-dto-vo#dto
 +
 
 +
https://www.baeldung.com/java-dto-pattern
 +
 
 +
Data Transfer Object,也称为数据传输对象,封装值以在进程或网络之间传输数据。
 +
 
 +
这有助于减少调用的方法的数量。通过在单个调用中包含多个参数或值,我们减少了远程操作中的网络开销。
 +
 
 +
这种模式的另一个优点是序列化逻辑的封装。它允许程序以特定格式存储和传输数据。
 +
 
 +
DTO 没有任何明确的行为。它基本上有助于通过将域模型与表示层解耦来使代码松散耦合。
 +
 
 +
==== 如何使用 DTO ? ====
 +
https://www.baeldung.com/java-pojo-javabeans-dto-vo#2-how-to-use-dto
 +
 
 +
DTO 具有扁平结构,没有任何业务逻辑。它们使用与 POJO 相同的格式。
 +
 
 +
DTO 仅包含与序列化或解析相关的存储、访问器和方法。
 +
 
 +
DTO 基本上映射到域模型,从而将数据发送到方法或服务器。
 +
 
 +
让我们创建 EmployeeDTO,它将创建员工所需的所有信息组织起来。我们将在优化与 API 交互的单个请求中将此数据发送到服务器:<syntaxhighlight lang="java">
 +
public class EmployeeDTO {
 +
 
 +
    private String firstName;
 +
    private String lastName;
 +
    private LocalDate startDate;
 +
 
 +
    // standard getters and setters
 +
}
 +
</syntaxhighlight>
 +
上面的 DTO 与不同的服务交互并处理数据流。这种 DTO 模式可以在任何服务中使用,没有任何框架限制。
 +
 
 +
同样功能,有的公司代码实现命名叫 XXXRequest。
 +
 
 +
 
 +
 
 +
 
  
 
=== VO ===
 
=== VO ===
View Object,视图对象,用于展示层,把某个指定页面的展示数据封装起来
+
https://www.baeldung.com/java-pojo-javabeans-dto-vo#vo
 +
 
 +
Value Object,也称为值对象,是一种特殊类型的对象,可以保存 java.lang.Integer 和 java.lang.Long 等值。
 +
 
 +
VO 应该总是覆盖 equals() 和 hashCode() 方法。VO 一般会封装数字、日期、字符串等小对象。它们遵循语义,即它们直接更改对象的值并传递副本而不是引用。
 +
 
 +
使值对象不可变是一种很好的做法。值的更改仅通过创建新对象发生,而不是通过更新旧对象本身的值发生。
 +
 
 +
这有助于理解两个创建相等的值对象应该保持相等的隐式约定。
 +
 
 +
示例定义 EmployeeVO 并且覆盖 equals() 和 hashCode() 方法:<syntaxhighlight lang="java">
 +
public final class EmployeeVO {
 +
 
 +
    private final String firstName;
 +
    private final String lastName;
 +
    private final LocalDate startDate;
 +
 
 +
    public EmployeeVO(String firstName, String lastName, LocalDate startDate) {
 +
        this.firstName = firstName;
 +
        this.lastName = lastName;
 +
        this.startDate = startDate;
 +
    }
 +
    // Getters
 +
 
 +
    @Override
 +
    public boolean equals(Object obj) {
  
 +
        if (this == obj) return true;
 +
        if (obj == null || getClass() != obj.getClass()) return false;
  
=== DTO ===
+
        EmployeeVO emp = (EmployeeVO) obj;
Data Transfer Object,用于展示层与服务层之间的数据传输对象
+
 
 +
        return Objects.equals(firstName, emp.firstName)
 +
          && Objects.equals(lastName, emp.lastName)
 +
          && Objects.equals(startDate, emp.startDate);
 +
    }
 +
 
 +
    @Override
 +
    public int hashCode() {
 +
        return Objects.hash(firstName, lastName, startDate);
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
特点是:
  
 +
属性用 private final 修饰;
  
=== BO ===
+
也有一说是 View Object
Business Object,业务对象,把业务逻辑封装为一个对象
 
  
 +
  
 
=== PO ===
 
=== PO ===
 
Persistent Object,持久化对象,和持久层(如数据库)形成对应的映射关系
 
Persistent Object,持久化对象,和持久层(如数据库)形成对应的映射关系
 +
 +
对应数据表的 Java 对象,属性列表应该和数据表中的字段完全一致。
 +
 +
如果一个对象,它的属性列表不多不少地准确对应了数据库中某一张表的字段列表,
 +
 +
并且 Mapper 可以直接调用 save|insert、delete、update、list 返回 PO 对象进行封装的,那么它就是一个 PO。
  
  
第21行: 第254行:
 
=== DO ===
 
=== DO ===
 
Domain Object,领域对象,从现实世界中抽象出来的有形或无形的业务实体。
 
Domain Object,领域对象,从现实世界中抽象出来的有形或无形的业务实体。
 +
 +
 +
=== Entity ===
 +
实体对象由 Entity 承担
 +
 +
 +
 +
===SO===
 +
 +
Service Object,服务对象。
 +
 +
在典型的分层应用程序体系结构中,有3个不同的层:
 +
 +
# 表示/视图层
 +
# 服务/业务层
 +
# 数据访问/持久层
 +
 +
表示或视图层由负责传入请求接口的所有“Web”或“Rest”类组成;
 +
 +
顾名思义,数据访问或持久层只是一个用于封装数据相关逻辑的层,DAO 和 DTO 模式实际上都位于这一层;
 +
 +
最后,服务层是负责核心业务逻辑的层,因此这是服务对象所在的层。
 +
 +
服务对象(SO)只是一个用于封装业务逻辑的对象。
 +
 +
这个 SO 的一个常见示例是服务类。比如:ItemService
 +
 +
 +
是为了处理包含多个 POJO 对象(即对多个表的数据操作)时,进行事务的管理。
 +
 +
Service 层(其接口的实现类)被注入一个或多个 DAO 对象,以完成有意义的数据操作。
 +
 +
一般,Service 中的一个方法为一个事务,里面调用多个 DAO 对象的方法完成一个业务逻辑上的操作。
 +
 +
 +
 +
=== BO ===
 +
Business Object,业务对象。
 +
 +
它是一个包含业务逻辑代码的对象。
 +
 +
简而言之,BO 几乎就是一个 SO。
 +
 +
这只是 enterprise Java 世界中的术语问题。
 +
 +
但是,一些开发人员还在其他地方使用 BO。
 +
 +
你可能已经看到包含大量业务逻辑但实际上并没有被归类为 'Service Object'(服务对象)的类,因为它没有向调用 Web 层的 REST 控制器暴露‘Service’(服务)层约定。
 +
 +
这是 BO 与 SO 的不同之处。
 +
 +
当可以将业务逻辑代码放在 SO 中以有效地将 SO 转换为 BO 时,可以考虑将业务逻辑代码抽象到它自己的类—— BO 中。
 +
 +
让 SO 本身成为许多单独业务对象的“facade”(外观)或“orchestrator”(协调器)。
 +
 +
BO 和 SO 是 N:1的关系;
 +
 +
SO 中的一个方法可能需要调用多个 BO 的方法才能实现;
 +
{| class="wikitable"
 +
! colspan="4" |AAAController
 +
|-
 +
! colspan="2" |BBBService
 +
! colspan="2" |CCCService
 +
|-
 +
!DDDBO
 +
!EEEBO
 +
!FFFBO
 +
!GGGBO
 +
|}
 +
 +
 +
 +
 +
 +
=== Q&A ===
 +
[[关于 POJO]]
 +
 +
[[关于 Java Bean]]
 +
 +
[[POJO 和 Java Bean 的区别是什么?]]
 +
 +
[https://www.jihongchang.top/index.php/%E5%A4%9A%E4%B8%AA%E8%A1%A8%E5%AF%B9%E5%BA%94%E7%9A%84%E4%B8%80%E4%B8%AA_PO_%E6%98%AF%E5%8D%95%E7%8B%AC%E6%8A%BD%E8%B1%A1%E5%87%BA%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%A5%BD%EF%BC%8C%E8%BF%98%E6%98%AF%E5%9C%A8%E4%B8%BB%E8%A6%81%E5%BA%94%E7%94%A8%E7%9A%84%E4%B8%80%E5%BC%A0%E8%A1%A8%E5%AF%B9%E5%BA%94%E7%9A%84_PO_%E9%87%8C%E8%BF%BD%E5%8A%A0%E6%9B%B4%E5%A4%9A%E7%9A%84%E5%B1%9E%E6%80%A7%E7%94%A8%E8%B5%B7%E6%9D%A5%E6%9B%B4%E5%A5%BD%EF%BC%9F 多个表对应的一个 PO 是单独抽象出一个类好,还是在主要应用的一张表对应的 PO 里追加更多的属性用起来更好?]
 +
 +
[https://www.jihongchang.top/index.php/Java_%E4%B8%AD%EF%BC%8CDTO_%E5%92%8C_VO_%E7%9A%84%E5%8C%BA%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F Java 中,DTO 和 VO 的区别是什么?]
 +
 +
[https://www.jihongchang.top/index.php/Java_%E4%B8%AD%EF%BC%8CDAO_%E8%BF%94%E5%9B%9E%E7%9A%84%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%9C%E7%94%A8_DTO_%E5%B0%81%E8%A3%85%E8%BF%98%E6%98%AF_PO_%E5%B0%81%E8%A3%85%EF%BC%9F Java 中,DAO 返回的查询结果用 DTO 封装还是 PO 封装?]
 +
 +
[[在 Java 中,DAO 的方法应该返回 VO 还是 DTO ?]]
 +
 +
[[在 Java 中,Controller 层应该调用 BO 还是 SO?]]
 +
 +
[[在 Java 中,BO 介于哪两者之间?]]
 +
 +
[[Controller 接收参数之后,按参数判断执行不一样的业务逻辑,参数的判断规则应该实现在 Controller 的方法里还是 Service 的方法里?]]
 +
 +
 +
 +
=== 总结 ===
 +
和之前在JD工作过的同事探讨的时候,听他说他参与的项目中是有 DTO 和 VO 的,DTO 用来封装复杂的查询结果,VO 用来封装控制层响应给接口的复杂内容。
 +
 +
表按照业务建在不同的数据库,很少多表联查,甚至是一个线程挨个表去查的。
 +
 +
 +
 +
 +
===参考资料===
 +
优先级从高到底
 +
 +
https://www.baeldung.com/java-pojo-javabeans-dto-vo#:~:text=VO%2C%20also%20known%20as%20the,hold%20values%20such%20as%20java.
 +
 +
https://www.baeldung.com/java-dto-pattern
 +
 +
https://chat.openai.com/chat
 +
 +
https://blog.devgenius.io/dao-dto-po-so-bo-vo-wtf-6673c9dd5437
 +
 +
https://www.bilibili.com/video/BV18L4y1F7PU
 +
 +
https://blog.csdn.net/weixin_43847283/article/details/121876570
 +
 +
https://www.jianshu.com/p/6c440b06cf6d

2023年8月17日 (四) 07:05的最新版本

开篇

PO、VO、DTO 都是含义,

当一个对象的属性字段和数据库中某一张表的字段不多不少准确对应,可以通过调用 DAO(Mapper)直接对应进行 CRUD 操作的时候,这个对象就是一个 PO ;

当用一个对象来封装 http 请求发送到 Controller 的数据的时候,用它封装 DAO 查询结果数据的时候,这个对象就是一个 DTO;

当用一个对象来封装返回给 http 请求调用响应数据的时候,它就是一个 VO。


如果是一个非常简单的业务,只用一个类就能满足以上三个条件,那么这个类的对象就既是 PO,又是 DTO,同时还是 VO:

比如对应这么一张表 student (id, name, age) 有

public class Student {

    private long id;

    private String name;

    private Integer age;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

这么一个类,

在 DAO 里调用 save、update 直接就可以操作表中一条记录的时候,它起到的就是作为一个 PO 的作用;

当通过 DAO 查询,用它封装查询结果数据并返回给上层 Servcie 和 在 Controller 层封装请求数据、在 Service 层、对象与对象之间封装参数进行传递的时候,它起到的就是作为一个 DTO 的作用;

当封装由 Controller 层影响给 http 请求调用响应数据的时候,它起到的就是作为一个 VO 的作用。

无关于一个类是什么样的命名后缀。

Student(或命名为 StudentPO)和 StudentDTO、StudentVO 这样命名的多个类存在的意义在于:

按照单一职责原则创建的多个类的对象对需求进行解耦,作用在不同的应用场景下、满足不同的需求,使得它们之间不会互相干涉、影响。

比如:

今天的需求实现需要 http incoming 再多传一个参数了;

明天前端调用要求 http 请求 response 需要再多返回一个参数了;

后天数据库的表里又多加了一个字段了;

如果只使用一个类,就难以准确地满足这些后序的扩展需求,所以才要有 DTO、PO、VO 这样不同的概念。




对比

DTO POJO VO
名称 Data Transfer Object

数据传输对象

Plain Old Java Object

普通旧 Java 对象

Value Object

值对象

相同点
不同点
使用场景 封装 Web 请求传入的值
SO BO
名称 Service Object

服务对象

Business Object

业务对象

使用场景 作为若干个 BO (单个业务对象)的 facade 提供给 REST controller 调用 主要封装业务逻辑
不同点 供 REST controller 调用;

业务逻辑代码少;

直接和 DAO 打交道,包含事务处理;

供 SO 调用;

业务逻辑代码多;

不直接和DAO打交道,不包含事务处理

相同点 都包含业务逻辑代码的实现;
意义 事务处理;

隐藏业务逻辑实现;

封装具体业务逻辑实现的细节




DTO

https://www.baeldung.com/java-pojo-javabeans-dto-vo#dto

https://www.baeldung.com/java-dto-pattern

Data Transfer Object,也称为数据传输对象,封装值以在进程或网络之间传输数据。

这有助于减少调用的方法的数量。通过在单个调用中包含多个参数或值,我们减少了远程操作中的网络开销。

这种模式的另一个优点是序列化逻辑的封装。它允许程序以特定格式存储和传输数据。

DTO 没有任何明确的行为。它基本上有助于通过将域模型与表示层解耦来使代码松散耦合。

如何使用 DTO ?

https://www.baeldung.com/java-pojo-javabeans-dto-vo#2-how-to-use-dto

DTO 具有扁平结构,没有任何业务逻辑。它们使用与 POJO 相同的格式。

DTO 仅包含与序列化或解析相关的存储、访问器和方法。

DTO 基本上映射到域模型,从而将数据发送到方法或服务器。

让我们创建 EmployeeDTO,它将创建员工所需的所有信息组织起来。我们将在优化与 API 交互的单个请求中将此数据发送到服务器:

public class EmployeeDTO {

    private String firstName;
    private String lastName;
    private LocalDate startDate;

    // standard getters and setters
}

上面的 DTO 与不同的服务交互并处理数据流。这种 DTO 模式可以在任何服务中使用,没有任何框架限制。

同样功能,有的公司代码实现命名叫 XXXRequest。



VO

https://www.baeldung.com/java-pojo-javabeans-dto-vo#vo

Value Object,也称为值对象,是一种特殊类型的对象,可以保存 java.lang.Integer 和 java.lang.Long 等值。

VO 应该总是覆盖 equals() 和 hashCode() 方法。VO 一般会封装数字、日期、字符串等小对象。它们遵循语义,即它们直接更改对象的值并传递副本而不是引用。

使值对象不可变是一种很好的做法。值的更改仅通过创建新对象发生,而不是通过更新旧对象本身的值发生。

这有助于理解两个创建相等的值对象应该保持相等的隐式约定。

示例定义 EmployeeVO 并且覆盖 equals() 和 hashCode() 方法:

public final class EmployeeVO {

    private final String firstName;
    private final String lastName;
    private final LocalDate startDate;

    public EmployeeVO(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }
    // Getters

    @Override
    public boolean equals(Object obj) {

        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        EmployeeVO emp = (EmployeeVO) obj;

        return Objects.equals(firstName, emp.firstName)
          && Objects.equals(lastName, emp.lastName)
          && Objects.equals(startDate, emp.startDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName, startDate);
    }
}

特点是:

属性用 private final 修饰;

也有一说是 View Object

PO

Persistent Object,持久化对象,和持久层(如数据库)形成对应的映射关系

对应数据表的 Java 对象,属性列表应该和数据表中的字段完全一致。

如果一个对象,它的属性列表不多不少地准确对应了数据库中某一张表的字段列表,

并且 Mapper 可以直接调用 save|insert、delete、update、list 返回 PO 对象进行封装的,那么它就是一个 PO。


DO

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


Entity

实体对象由 Entity 承担


SO

Service Object,服务对象。

在典型的分层应用程序体系结构中,有3个不同的层:

  1. 表示/视图层
  2. 服务/业务层
  3. 数据访问/持久层

表示或视图层由负责传入请求接口的所有“Web”或“Rest”类组成;

顾名思义,数据访问或持久层只是一个用于封装数据相关逻辑的层,DAO 和 DTO 模式实际上都位于这一层;

最后,服务层是负责核心业务逻辑的层,因此这是服务对象所在的层。

服务对象(SO)只是一个用于封装业务逻辑的对象。

这个 SO 的一个常见示例是服务类。比如:ItemService


是为了处理包含多个 POJO 对象(即对多个表的数据操作)时,进行事务的管理。

Service 层(其接口的实现类)被注入一个或多个 DAO 对象,以完成有意义的数据操作。

一般,Service 中的一个方法为一个事务,里面调用多个 DAO 对象的方法完成一个业务逻辑上的操作。


BO

Business Object,业务对象。

它是一个包含业务逻辑代码的对象。

简而言之,BO 几乎就是一个 SO。

这只是 enterprise Java 世界中的术语问题。

但是,一些开发人员还在其他地方使用 BO。

你可能已经看到包含大量业务逻辑但实际上并没有被归类为 'Service Object'(服务对象)的类,因为它没有向调用 Web 层的 REST 控制器暴露‘Service’(服务)层约定。

这是 BO 与 SO 的不同之处。

当可以将业务逻辑代码放在 SO 中以有效地将 SO 转换为 BO 时,可以考虑将业务逻辑代码抽象到它自己的类—— BO 中。

让 SO 本身成为许多单独业务对象的“facade”(外观)或“orchestrator”(协调器)。

BO 和 SO 是 N:1的关系;

SO 中的一个方法可能需要调用多个 BO 的方法才能实现;

AAAController
BBBService CCCService
DDDBO EEEBO FFFBO GGGBO



Q&A

关于 POJO

关于 Java Bean

POJO 和 Java Bean 的区别是什么?

多个表对应的一个 PO 是单独抽象出一个类好,还是在主要应用的一张表对应的 PO 里追加更多的属性用起来更好?

Java 中,DTO 和 VO 的区别是什么?

Java 中,DAO 返回的查询结果用 DTO 封装还是 PO 封装?

在 Java 中,DAO 的方法应该返回 VO 还是 DTO ?

在 Java 中,Controller 层应该调用 BO 还是 SO?

在 Java 中,BO 介于哪两者之间?

Controller 接收参数之后,按参数判断执行不一样的业务逻辑,参数的判断规则应该实现在 Controller 的方法里还是 Service 的方法里?


总结

和之前在JD工作过的同事探讨的时候,听他说他参与的项目中是有 DTO 和 VO 的,DTO 用来封装复杂的查询结果,VO 用来封装控制层响应给接口的复杂内容。

表按照业务建在不同的数据库,很少多表联查,甚至是一个线程挨个表去查的。



参考资料

优先级从高到底

https://www.baeldung.com/java-pojo-javabeans-dto-vo#:~:text=VO%2C%20also%20known%20as%20the,hold%20values%20such%20as%20java.

https://www.baeldung.com/java-dto-pattern

https://chat.openai.com/chat

https://blog.devgenius.io/dao-dto-po-so-bo-vo-wtf-6673c9dd5437

https://www.bilibili.com/video/BV18L4y1F7PU

https://blog.csdn.net/weixin_43847283/article/details/121876570

https://www.jianshu.com/p/6c440b06cf6d