【问题标题】:Should I consider using DTO for Spring Rest Controller layers instead of Entities?我应该考虑将 DTO 用于 Spring Rest Controller 层而不是实体吗?
【发布时间】:2017-05-06 12:00:11
【问题描述】:

我作为初学者已经开始了一个 Spring Rest 项目。我的大多数实体都有超过 15-20 个属性,并不是 UI 层需要所有属性。

我正在考虑使用 DTO,原因如下:

  1. 尽量减少出于信息隐私原因发送的不必要信息。
  2. 为了提高性能而减小 json 字符串的大小。
  3. 使用相同实体的不同 UI 可能具有不同的业务验证(即强制/可选字段)。我可以为同一个实体创建 2 个 DTO 并相应地注释验证。

我正在考虑使用 DTO 将多个实体合并在一起,根据角色隐藏/显示某些 UI 的某些信息,但是当我需要保留详细信息时,我必须将 DTO 信息“拆分/复制”回不同的实体.

员工 - 能够查看下一级经理的绩效评估和 cmets。 经理 - 可以输入 cmets 进行绩效评估,并显示员工的加薪(员工 UI 中没有显示),但无法查看员工当前的工资。 HR - 能够查看所有 UI 的所有详细信息。

我想知道是否有更好的方法来处理这些问题,或者我的项目是否朝着正确的方向前进?

参考:http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

【问题讨论】:

  • 有很多方法,比如使用 JSON 视图。但坦率地说,我发现使用 DTO 更简单、更简洁。它避免了给一个实体两个责任。它还可以更轻松地处理延迟加载的属性。不过,我非常讨厌 Dozer:它将实体和 DTO 耦合在一起,使得使用不可变 DTO 变得困难,并且使代码无法安全地重构。
  • 我发现单独使用实体无法满足我的要求,因此我正在查看 DTO 而不是实体。我也会看看 JSON 视图。谢谢!

标签: java spring rest


【解决方案1】:

我总是使用 DTO 将我的视图与我的 JPA 实体分离。 除了您列出的 3 个原因之外,我还可以添加以下内容。

  • JPA 通常在父子之间有双向引用,其中一个是真实的(存在于 DB 中),另一个是合成的。序列化为 JSON 时,您只有父子关系,即合成关系。
  • 如果直接反序列化为实体,则必须对分离的实体和合并有一个完整的了解。如果您曾经尝试过合并大型循环实体图,您就会知道这不是在公园里散步。
  • 对于 JSON 视图,性能也很重要。如果您使用实体生成 JSON,则必须加载所有列。使用投影通常更有效,然后将所需的列直接选择到 DTO 中。
  • 如果您有 API,则可以将 DTO 放入一个单独的模块中,该模块可以被其他人作为依赖项重用,而您永远不想对实体类这样做。
  • JB Nizet 提到了不变性,这也是一个很好的观点。使用@JSONCreator,您可以获得不可变的 DTO,这可能具有一些优势 - 尽管大多数情况下 DTO 不用于多线程上下文,因此不需要。

在我的项目中,我总是使用Lombok 来生成访问方法,这意味着 DTO 通常只包含数据字段(有时输入 DTO 具有验证器或实用程序方法)。这使得它们非常容易创建/修改,并且很容易与包含逻辑的类区分开来。与编写业务逻辑相比,创建 DTO 不需要花费太多时间,因此这种解耦的成本非常低,而且我真的相信它可以让代码更容易阅读。

【讨论】:

  • @JSONCreator 应该做什么以及如何使用它?
  • 通常 DTO 是可变 POJO,因此它们具有默认构造函数和设置器,您可以在带参数的构造函数上使用 JSonCreator,在每个参数上使用 JsonProperty,这允许您构造不可变的 DTO ,在某些情况下可能很有用。更多信息在这里cowtowncoder.com/blog/archives/2011/07/entry_457.html
【解决方案2】:

最好使用 DTO 有一个干净的架构,使用 DTO,当你修改 Table 时,FrontEnd 不会有任何变化。

但最好小心使用。

  1. DTO 不是免费的,您应该为可维护性、代码行(更多代码、更多错误)付费,您应该对投资回报率有所了解。
  2. 如果您有 5 个以上的开发人员,并且您为一个大项目工作,那么您可以。
  3. 对于一个新的From Scratch项目,不要从DTO入手,它太重了,首先让你的应用程序运行起来,专注于业务层,而不是控制器或表示。
  4. 您不需要为每个实体创建DTO,只需创建您需要的,实际上,您总是可以通过使用JsonView或创建新的API来解决问题,这样更有利于维护。
  5. 您可以使用 JsonView、JsonIgnore 代替 DTO 来自定义响应,它非常适合中小型项目。
  6. 使用映射器库,我建议简单项目使用 modelMapper,复杂项目使用 Orika,注意,Lombok 与这些映射器库不兼容

祝你好运。

【讨论】:

    猜你喜欢
    • 2022-01-19
    • 1970-01-01
    • 2015-11-22
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 2023-02-05
    相关资源
    最近更新 更多