我是否应该将实体转换为存储库对象内的 DTO 并将其返回到服务层?

2022-09-04 21:38:59

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

我是否应该将实体转换为存储库对象内的 DTO 并将其返回到服务层?

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

现在我被困在我的Servlet(Servie Layer)中,例如,尝试从中检索所有对象:RestaurantRestaurantOwnerRepository

// RestaurantOwnerService (Servlet)

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

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

    return null;
}

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

例如,如果我将每个转换为a,情况就不会是这样 - 但是我应该这样做吗?RestaurantRestaurantDTO

基本变化:

// 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


答案 1

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

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

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

您的“高级”设置

  • 持久层
    • 使用休眠(提供@Entity注释的对象)
    • 也许还有其他东西,太
  • 存储库层(不清楚要返回的内容)
  • 服务层(GWT Servlets,提供与客户端共享的DTO)

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

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

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

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

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

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


答案 2

推荐