我应该将实体转换为 Repository 对象内的 DTO 并将其返回到服务层吗? [英] Should I convert an entity to a DTO inside a Repository object and return it to the service layer?

查看:22
本文介绍了我应该将实体转换为 Repository 对象内的 DTO 并将其返回到服务层吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to get an answer to the two quite similar questions here:

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

Should I convert an entity to a DTO inside a Repository object and return it to the Service Layer?

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

Is it okay to return DTO objects from the Repository Layer?

现在我被困在我的 Servlet(服务层)中,例如尝试从 RestaurantOwnerRepository 中检索所有 Restaurant 对象:

Right now I am stuck in my Servlet (Servie Layer) that e.g. tries to retrieve all Restaurant objects from a RestaurantOwnerRepository:

// RestaurantOwnerService (Servlet)

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

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

    return null;
}

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

where Restaurant is a @Entity annotated class - which appears to be the first thing I shouldn't do because the Service Layer does now know about a very low-level object which imho violates the attempt to abstract my data in each layer.

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

That wouldn't be the case if I e.g. converted each Restaurant to a RestaurantDTO - but should I do that?

基本改变:

// 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);
}

并为 每个 实体设置一个 util ConvertEntity,例如:

and have a util ConvertEntity for every entity like this for example:

public class ConvertEntity {

    public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) {
        // ...
    }

}

但这对我来说并不是最好的解决方案..我能在这里做什么?

but this just does not feel like the best solution to me.. what could I do here?

需要提及的一件重要事情是,这来自一个 GWT 项目.这意味着我正在使用例如RestaurantDTO 位于服务器端和客户端,因为它包含在一个共享 项目中.

One important thing to mention would be that this comes form a GWT project. That means that I am using e.g. RestaurantDTO on the server and on the client side as it is contained inside a shared project.

推荐答案

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

It's more clear now after your comment. Let's try again:

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

First, some clarifications: Your RestaurantOwnerRepository implements the repository pattern. Your @Entity annotated objects are hibernate entities and also DAO proxies. Your RestaurantOwnerService is a GWT-Service which can only return a DTO shared with the client and server.

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

So in a very simple server-side setup, you have a DB-Backend, access to the data via hibernate as a persistence layer, and a service layer as rest-service. In such a setup your hibernate entities are shared among the whole server side code. Your service layer is converting the entities to json format, for example. Deal?

您的高级"设置

  • 持久层
    • 使用 Hibernate(提供 @Entity-Annotated 对象)
    • 也许还有其他东西

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

    Definition of Repository-Layer: In my opinion, it's an abstraction for different data/persistence layers. It doesn't provide business logic, which is more the purpose of a further business layer. The business layer compiles the outputs of the upper layer together, makes computations and returns the results. But looking according to your comment, this may also be the case in your repository layer. But it's ok for our clarification.

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

    Your question: Is it okay to return DTO objects from the Repository Layer?

    答案: 不,从存储库"层返回 DTO 并不是很好.

    Answer: No, it is not really okay to return a DTO from the "repository" layer.

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

    Why: 1. Your DTO is a domain entity transferred into a format which can be sent to the client side. It has limitations so that some server side libraries cannot be used in them. 2. Consider the case that you also want to provide other service layers. A REST-Interface maybe, another GUI-Framework maybe. They all have their own limitations for transferring the domain entities. Do you really want to duplicate the repository layer for each service layer? 3. Consider the case where you want to extend your repository/business layer so that it will use the output of your RestaurantOwnerRepository. Do you really want to work on DTOs there?

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

    These are why the creation of a DTO is the purpose of a service layer. So the DTO is shared among the client side, and your service layer. In the same sense, you need objects, shared among the service layer and your repository layer. I call these domain entities. These are returned from the repository layer and used by the service layer. Again the same between the repository layer and persistence layer. The persistence layer for example returns the Hibernate entities which are used on the repository layer.

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

    In most cases, it is ok to propagate your objects from multiple layers downwards. So you can return your hibernate entites from the repository layer to the service layer. Newer versions of GWT even allow to use JPA-entities on the client side with a special setup. So your service layer can further return your persistence entities.

    这篇关于我应该将实体转换为 Repository 对象内的 DTO 并将其返回到服务层吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆