Spring 实体应该在服务中转换为 Dto 吗?

标签 spring spring-mvc

在评论后 question .我开始研究,但我仍然感到困惑。
实体在返回 Controller 之前应该转换为Dto吗?对我来说,这听起来不太实用。

最佳答案

我们谈论的是软件架构,并且与往常一样,当我们谈论软件架构时,有上千种做某事的方法以及关于什么是最好的方法的许多意见。但是没有最好的办法,一切都有优点和缺点。请记住这一点!

通常你有不同的层:

  • 用于存储数据的持久层
  • 对数据进行操作的业务层
  • 用于公开数据的表示层

通常,每一层都会使用自己的对象:

  • 持久层:存储库、实体
  • 业务层:服务、域对象
  • 表示层: Controller 、DTO

这意味着每个层只能使用自己的对象,而永远不会将它们传递给另一个层。

为什么?因为您希望将每一层与其他层分开。如果您要在 Controller 中使用实体,您的演示文稿将取决于您的数据的存储方式。这真的很糟糕。您的 View 与数据的存储方式无关。它甚至不应该知道这些或数据是如何存储的。

想一想:您更改了数据库模型,例如您将一个新列添加到您的数据库表之一。如果您将实体传递给您的 Controller (或者更糟糕的是:您的 Controller 将它们公开为 JSON),数据库的更改将导致您的演示文稿发生更改。如果实体直接暴露为 JSON,这甚至可能导致 JavaScript 或其他使用 JSON 的客户端发生变化。因此,数据库中的简单更改可能需要更改 JavaScript 前端,因为您将层耦合得非常紧密。您绝对不希望在实际项目中出现这种情况。

怎么做?你怀疑这是否实用,所以只是一个小例子,说明如何在(伪)代码中做到这一点:

class Repository {
    public Person loadById(Long id) {
        PersonEntity entity = loadEntityById(id);
        Person person = new Person();
        person.setId(entity.getId());
        person.setName(entity.getFirstName + " " + entity.getLastName());
        return person;
    }
}

在此示例中,您的存储库将在内部使用实体。没有其他层知道或使用这个实体!它们是这个特定层的实现细节。因此,如果要求存储库返回一个“人”,它会在实体上工作,但它会返回一个域对象。因此,在需要更改实体的情况下,保存与 repo 一起使用的域层。正如您在名称中看到的那样,域和数据库可能不同。虽然数据库将名称存储在名字和姓氏中,但域只知道一个名称。这是它如何存储名称的持久性的细节。

Controller 和 DTO 也是如此,只是另一层。

关于Spring 实体应该在服务中转换为 Dto 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34084203/

相关文章:

java - Hibernate Criteria : nested exception is org. hibernate.QueryException:无法解析属性:

java - 将参数传递给来自 xml 的不同切入点的相同切面方法

java - Spring REST XML 服务不接受 XML 作为 "accept" header

java - 服务器断开连接后如何在 Spring MVC 中保持客户端 session 处于 Activity 状态

html - 如何将服务器端 Shiny 应用程序嵌入到 JSP 页面中而不在其他地方公开该应用程序

java - Spring MVC 相当于 ASP.NET RouteData

java - 如何在spring-mvc中的同一个jsp页面的同一个 Controller 上创建两个操作

java - Spring Boot ContextStoppedEvent 未被调用

java - Spring boot应用程序-Tomcat部署-无法确定合适的驱动程序类

java - 创建具有不同属性的同一类的多个 bean 的最干净方法