MVC架构DTO /模型映射/转换

时间:2016-01-25 08:44:37

标签: java spring model entity dto

使用Spring MVC,我们通常会看到Controller,Service和Repository层。 Repository层使用Entity模型,它与数据库一对一映射。我想到了 -

  1. 服务层应该使用相同的实体模型吗?
  2. 服务层应该使用单独的域模型吗?如果是,则应在服务层中完成往复映射?
  3. Controller层应该使用相同的域模型吗?
  4. Controller层应该使用单独的DTO模型吗?如果是,则应在Controller层中完成往返映射?
  5. 我们有没有简单的方法来进行映射而无需编写过多冗长的代码?我过去几次使用过Dozer。
  6. 这个问题可能已被提出,但我找不到。所以请原谅我重复的问题。

3 个答案:

答案 0 :(得分:5)

  1. 否。该服务应该对Repository对象返回的Entity模型起作用。
  2. 否。控制器应使用DTO。 DTO应包含表单字段和验证注释(如果您使用的是JSR303)。
  3. 是。 DTO用于Controller层。 DTO应该公开一个接受实体模型的构造函数。实体模型到DTO的转换是在此构造函数中完成的。实体模型的情况相同。实体模型还应该公开一个重载的构造函数,它接受DTO对象作为参数。应在此处将DTO转换为实体模型。
  4. DTO的重载构造函数(实体模型为arg)和实体模型(DTO为arg)是详细的。

答案 1 :(得分:4)

1)是的,

2)不,

3,4)使用实体进行输出,但使用CommandObjects和DTO(但不是实体)进行输入。这取决于您的体系结构,但是您不希望客户端对您实体的每个字段进行操作,那么您需要将用于请求映射(命令对象)的对象与您的域实体分开。

答案 2 :(得分:0)

整个服务层使用的实体模型应该相同。 根据您的体系结构和应用程序的复杂性,您可能希望在服务和控制器层中使用不同的域模型。 我的建议是:

  • 服务始终对使用数据库检索和存储的实体起作用
  • 服务始终将DTO或简单类型作为参数,并且仅返回DTO。为什么?由于DTO与数据库分离,因此您既不会遇到LazyInitializationException,也不必使用open-session-in-view anti-pattern
  • 将DTO视为服务和控制器之间共享的唯一模型
  • 对于实体与DTO对象之间的映射,我建议使用ModelProjector。它非常简单,精益且占地面积最小

ModelProjector通过匹配属性名称将一个模型映射到另一个模型。如果它们不匹配,则可以通过注释告诉它。也可以使用非常简单的注释将复杂的实体层次结构映射到“扁平化”的数据结构上。实体类保持不变。