在Spring Boot项目中,将实体转换为DTO应该放在哪里?

11

我正在开发一个基于Spring Boot(MVC,DATA,JPA...)和Angular的项目。

我在两个选项之间犯难,尽管两者都没有任何问题。

从架构角度来看,哪一个是最好的或者哪一个被使用得最多。

我的问题是什么是从实体到DTO转换的最佳方法

选项1:目前我正在实施的方案。

我将转换放在控制器中。在我的控制器中,我调用一个服务方法来获取一系列实体。然后,我使用ModelMapper将实体列表转换为DTO列表并将结果返回给前端。

Entity ==> Repository ==> Service ==> Controller ==> ModelMapper ==> Return DTO
  • 优点: 服务层始终会返回实体对象(可重复使用)

  • 缺点: 控制器中有很多代码(如果我需要解析列表...)

选项2 :

将转换放在服务层中。

因此,我的服务层将返回DTO的列表,而不是实体列表。

Entity ==> Repository ==> Service ==> ModelMapper ==> Controller  ==> Return DTO
  • 优点:服务返回的对象将直接返回到前端(控制器中没有太多代码)

  • 缺点:我不知道 ^^'

  • 优点:服务返回的对象将直接返回到前端(控制器中没有太多代码)

  • 缺点:我不知道 ^^'


3
我认为将转换留在服务层会更好,因为您的控制器与实体无关。此外,在事务上下文之外调用实体的getter方法可能会导致问题,如果它具有复杂的结构。您可以参考此链接以了解将实体转换为DTO的有效方法:https://www.thetechnojournals.com/2019/10/entity-object-conversion-to-dto-object.html - Ashok Prajapati
3
service===> Facade ===> ModelMapper之间增加一个额外的层。Facade将会从service获取实体并将其转换为DTO,同时处理GET请求,反之,在POST/PUT请求中也是如此。它还可以使你的控制器和服务类保持更清晰。 - rdj7
感谢您的回复。@AshokPrajapati 这就是我正在使用的。 - Mehdi Ayari
3个回答

3

你好,请问你在说哪个原则? - Marcos
你好 @Marcos,我会遵循单一职责原则,将服务类命名为 {something} 转换器。 - Caffeine Coder

3
我认为将实体转换成DTO的更好方式是:
  • 如果您在服务中不需要使用实体,则只需在仓库层将实体转换为DTO。此外,如果您正在使用Spring Data JPA,则可以直接将实体转换为DTO而无需任何额外的代码。但是,如果您编写了无法满足查询的复杂查询,则可以在存储库实现内部进行转换。这样做可以确保没有服务会获取其不必要的数据。不会暴露敏感数据。

  • 如果您真的需要实体并且没有其他办法,请在服务层将其转换为DTO,因为控制器绝不能访问不应该访问的数据。不应将敏感数据公开到控制器级别。这不是一个好的设计。

我认为这些是您可以进行实体转换的方法,但最佳设计是在仓库本身将实体转换为DTO。
希望这能帮助您解决问题。
祝您好运!

2
根据您的项目结构,最好的方式是使用。然而,如果您总是在控制器中调用服务,应该使用选项2,然后它将返回所需的结果。
此外,如果您想减少方法中转换的大量代码,可以使用@Component创建转换器类来映射实体和DTO。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接