我应该将一个实体转换为 Repository 对象内的 DTO 并将其 return 转换为服务层吗?
Should I convert an entity to a DTO inside a Repository object and return it to the service layer?
我想在这里找到两个非常相似的问题的答案:
Should I convert an entity to a DTO inside a Repository object and return it to the Service Layer?
或
Is it okay to return DTO objects from the Repository Layer?
现在我卡在我的 Servlet(Servie 层)中,例如尝试从 RestaurantOwnerRepository
:
中检索所有 Restaurant
对象
// RestaurantOwnerService (Servlet)
@Override
@Transactional
public List<RestaurantDTO> getAvailableRestaurants() {
List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());
return null;
}
其中 Restaurant
是 @Entity
注释 class - 这似乎是我不应该做的第一件事,因为服务层现在知道一个非常低级别的恕我直言,该对象违反了在每一层中抽象我的数据的尝试。
如果我,例如,情况就不是这样了。将每个 Restaurant
转换为 RestaurantDTO
- 但我应该这样做吗?
基本变化:
// RestaurantOwnerRepository
@Override
public List<Restaurant> getRestaurants(String sessionId) {
RestaurantOwner restaurantOwner = this.get(sessionId);
// .. getting restaurants ..
return availableRestaurants;
}
到
// RestaurantOwnerRepository
@Override
public List<Restaurant> getRestaurants(String sessionId) {
RestaurantOwner restaurantOwner = this.get(sessionId);
// .. getting restaurants ..
return ConvertEntity.convertRestaurants(availableRestaurants);
}
并为 每个 实体设置一个实用程序 ConvertEntity
例如:
public class ConvertEntity {
public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) {
// ...
}
}
但这对我来说并不是最好的解决方案..我能在这里做什么?
需要提及的重要一件事 是它来自 GWT 项目。这意味着我正在使用例如RestaurantDTO
在服务器端和客户端,因为它包含在 shared 项目中。
经过你的评论,现在更清楚了。我们再试一次:
首先澄清一下:
您的 RestaurantOwnerRepository
实现了存储库模式。您的 @Entity
注释对象是休眠实体,也是 DAO 代理。您的 RestaurantOwnerService
是一个 GWT 服务,它只能 return 一个与客户端和服务器共享的 DTO。
所以在一个非常简单的服务器端设置中,你有一个数据库后端,通过作为持久层的休眠访问数据,以及作为休息的服务层-服务。在这样的设置中,您的休眠实体在整个服务器端代码之间共享。例如,您的服务层正在将实体转换为 json 格式。交易?
您的 "advanced" 设置
- 持久层
- 使用 Hibernate(传递 @Entity-Annotated 对象)
- 也许还有其他东西
- 存储库层(你不清楚return)
- 服务层(GWT Servlet,交付与客户端共享的 DTO)
Repository-Layer的定义:在我看来,它是对不同data/persistence层的抽象。它不提供业务逻辑,这更多的是进一步业务层的目的。业务层将上层的输出汇总在一起,进行计算,return得出结果。但是根据您的评论来看,您的存储库层也可能是这种情况。但我们的澄清没关系。
您的问题:从存储库层 return DTO 对象可以吗?
答案:不,从"repository"层return一个DTO真的不行。
原因: 1.你的DTO是一个域实体,转换成可以发送到客户端的格式。它有一些限制,因此无法在其中使用某些服务器端库。 2.考虑你还想提供其他服务层的情况。可能是一个 REST 接口,也可能是另一个 GUI 框架。它们在传输域实体方面都有自己的局限性。您真的要为每个服务层复制存储库层吗? 3. 考虑一下您想要扩展 repository/business 层以便它使用 RestaurantOwnerRepository
的输出的情况。您真的想在那里从事 DTO 工作吗?
这就是为什么创建DTO是服务层的目的。因此,DTO 在客户端和您的服务层之间共享。同样,您需要在服务层和存储库层之间共享的对象。我称这些领域实体。这些是 return 从存储层中提取并由服务层使用的。存储层和持久层之间同样如此。持久层例如 return 在存储层上使用的 Hibernate 实体。
在大多数情况下,可以将对象从多层向下传播。所以你可以 return 你的休眠实体从存储库层到服务层。较新版本的 GWT 甚至允许通过特殊设置在客户端使用 JPA 实体。因此,您的服务层可以进一步 return 您的持久性实体。
我想在这里找到两个非常相似的问题的答案:
Should I convert an entity to a DTO inside a Repository object and return it to the Service Layer?
或
Is it okay to return DTO objects from the Repository Layer?
现在我卡在我的 Servlet(Servie 层)中,例如尝试从 RestaurantOwnerRepository
:
Restaurant
对象
// RestaurantOwnerService (Servlet)
@Override
@Transactional
public List<RestaurantDTO> getAvailableRestaurants() {
List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());
return null;
}
其中 Restaurant
是 @Entity
注释 class - 这似乎是我不应该做的第一件事,因为服务层现在知道一个非常低级别的恕我直言,该对象违反了在每一层中抽象我的数据的尝试。
如果我,例如,情况就不是这样了。将每个 Restaurant
转换为 RestaurantDTO
- 但我应该这样做吗?
基本变化:
// RestaurantOwnerRepository
@Override
public List<Restaurant> getRestaurants(String sessionId) {
RestaurantOwner restaurantOwner = this.get(sessionId);
// .. getting restaurants ..
return availableRestaurants;
}
到
// RestaurantOwnerRepository
@Override
public List<Restaurant> getRestaurants(String sessionId) {
RestaurantOwner restaurantOwner = this.get(sessionId);
// .. getting restaurants ..
return ConvertEntity.convertRestaurants(availableRestaurants);
}
并为 每个 实体设置一个实用程序 ConvertEntity
例如:
public class ConvertEntity {
public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) {
// ...
}
}
但这对我来说并不是最好的解决方案..我能在这里做什么?
需要提及的重要一件事 是它来自 GWT 项目。这意味着我正在使用例如RestaurantDTO
在服务器端和客户端,因为它包含在 shared 项目中。
经过你的评论,现在更清楚了。我们再试一次:
首先澄清一下:
您的 RestaurantOwnerRepository
实现了存储库模式。您的 @Entity
注释对象是休眠实体,也是 DAO 代理。您的 RestaurantOwnerService
是一个 GWT 服务,它只能 return 一个与客户端和服务器共享的 DTO。
所以在一个非常简单的服务器端设置中,你有一个数据库后端,通过作为持久层的休眠访问数据,以及作为休息的服务层-服务。在这样的设置中,您的休眠实体在整个服务器端代码之间共享。例如,您的服务层正在将实体转换为 json 格式。交易?
您的 "advanced" 设置
- 持久层
- 使用 Hibernate(传递 @Entity-Annotated 对象)
- 也许还有其他东西
- 存储库层(你不清楚return)
- 服务层(GWT Servlet,交付与客户端共享的 DTO)
Repository-Layer的定义:在我看来,它是对不同data/persistence层的抽象。它不提供业务逻辑,这更多的是进一步业务层的目的。业务层将上层的输出汇总在一起,进行计算,return得出结果。但是根据您的评论来看,您的存储库层也可能是这种情况。但我们的澄清没关系。
您的问题:从存储库层 return DTO 对象可以吗?
答案:不,从"repository"层return一个DTO真的不行。
原因: 1.你的DTO是一个域实体,转换成可以发送到客户端的格式。它有一些限制,因此无法在其中使用某些服务器端库。 2.考虑你还想提供其他服务层的情况。可能是一个 REST 接口,也可能是另一个 GUI 框架。它们在传输域实体方面都有自己的局限性。您真的要为每个服务层复制存储库层吗? 3. 考虑一下您想要扩展 repository/business 层以便它使用 RestaurantOwnerRepository
的输出的情况。您真的想在那里从事 DTO 工作吗?
这就是为什么创建DTO是服务层的目的。因此,DTO 在客户端和您的服务层之间共享。同样,您需要在服务层和存储库层之间共享的对象。我称这些领域实体。这些是 return 从存储层中提取并由服务层使用的。存储层和持久层之间同样如此。持久层例如 return 在存储层上使用的 Hibernate 实体。
在大多数情况下,可以将对象从多层向下传播。所以你可以 return 你的休眠实体从存储库层到服务层。较新版本的 GWT 甚至允许通过特殊设置在客户端使用 JPA 实体。因此,您的服务层可以进一步 return 您的持久性实体。