13

我试图在这里得到两个非常相似的问题的答案:

我应该将实体转换为存储库对象中的 DTO 并将其返回给服务层吗?

或者

从存储库层返回 DTO 对象可以吗?

现在我被困在我的 Servlet(服务层)中,例如试图Restaurant从以下位置检索所有对象RestaurantOwnerRepository

// RestaurantOwnerService (Servlet)

@Override
@Transactional
public List<RestaurantDTO> getAvailableRestaurants() {

    List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());

    return null;
}

Restaurant带注释的类在哪里@Entity-这似乎是我不应该做的第一件事,因为服务层现在确实知道一个非常低级的对象,恕我直言,这违反了在每一层中抽象我的数据的尝试。

如果我将 each 转换Restaurant为 a 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在服务器和客户端使用例如,因为它包含在共享项目中。

4

1 回答 1

12

在您发表评论后,现在更加清楚了。让我们再试一次:

首先,一些澄清:RestaurantOwnerRepository实现了存储库模式。您的@Entity注释对象是休眠实体,也是 DAO 代理。您RestaurantOwnerService是一个 GWT 服务,它只能返回与客户端和服务器共享的 DTO。

因此,在一个非常简单的服务器端设置中,您有一个 DB-Backend,通过 hibernate 作为持久层访问数据,以及作为 rest-service 的服务层。在这样的设置中,您的休眠实体在整个服务器端代码之间共享。例如,您的服务层正在将实体转换为 json 格式。交易?

您的“高级”设置

  • 持久层
    • 使用 Hibernate(提供 @Entity-Annotated 对象)
    • 也许还有其他东西
  • 存储库层(您不清楚要返回什么)
  • 服务层(GWT Servlets,提供与客户端共享的 DTO)

存储层的定义:在我看来,它是不同数据/持久层的抽象。它不提供业务逻辑,这更多是进一步业务层的目的。业务层将上层的输出编译在一起,进行计算并返回结果。但是根据您的评论,您的存储库层也可能是这种情况。但我们可以澄清一下。

您的问题:可以从存储库层返回 DTO 对象吗?

回答:不,从“存储库”层返回 DTO 并不是真的可以。

原因: 1. 你的 DTO 是一个域实体,转换成可以发送到客户端的格式。它有一些限制,因此某些服务器端库不能在其中使用。2. 考虑您还想提供其他服务层的情况。也许是一个 REST 接口,也许是另一个 GUI 框架。他们都有自己的转移域实体的限制。您真的要为每个服务层复制存储库层吗?3. 考虑您想要扩展存储库/业务层的情况,以便它使用您的RestaurantOwnerRepository. 你真的想在那里从事 DTO 工作吗?

这就是为什么创建 DTO 是服务层的目的。因此 DTO 在客户端和您的服务层之间共享。同样,您需要在服务层和存储库层之间共享的对象。我称这些域实体。这些从存储库层返回并由服务层使用。存储库层和持久层之间也是如此。例如,持久层返回在存储库层上使用的 Hibernate 实体。

在大多数情况下,可以从多个层向下传播您的对象。因此,您可以将您的休眠实体从存储库层返回到服务层。较新版本的 GWT 甚至允许通过特殊设置在客户端使用 JPA 实体。因此,您的服务层可以进一步返回您的持久性实体。

于 2015-07-31T10:12:04.580 回答