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

dis*_*ame 7 java gwt web-services abstraction-layer

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

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

要么

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

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

// RestaurantOwnerService (Servlet)

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

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

    return null;
}
Run Code Online (Sandbox Code Playgroud)

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

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

基本上改变:

// RestaurantOwnerRepository

@Override
public List<Restaurant> getRestaurants(String sessionId) {

    RestaurantOwner restaurantOwner = this.get(sessionId);

    // .. getting restaurants ..

    return availableRestaurants;
}
Run Code Online (Sandbox Code Playgroud)

// RestaurantOwnerRepository

@Override
public List<Restaurant> getRestaurants(String sessionId) {

    RestaurantOwner restaurantOwner = this.get(sessionId);

    // .. getting restaurants ..

    return ConvertEntity.convertRestaurants(availableRestaurants);
}
Run Code Online (Sandbox Code Playgroud)

ConvertEntity为这样的每个实体都有一个util ,例如:

public class ConvertEntity {

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

}
Run Code Online (Sandbox Code Playgroud)

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


值得一提的是,这是一个GWT项目.这意味着我RestaurantDTO在服务器和客户端使用,因为它包含在共享项目中.

fat*_*tih 10

你的评论后现在更清楚了.让我们再试一次:

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

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

您的"高级"设置

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

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

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

答:不,从"存储库"层返回DTO并不是真的可以.

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

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

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

  • 好吧,没有任何 `RestaurantOwnerRepository` 是真正的存储库(模式)。每个带有 @Entity 注释的类实际上都是一个 DAO,因为 Hibernate 围绕它包装了一个代理。我不明白为什么要在整个项目中共享 `@Entity` 类?只有服务器应该知道这些,恕我直言,它们的使用以存储库层结束。我也不明白你所说的“编译存储库对象”是什么意思。存储库层不应该返回已经是实体对象编译的业务对象吗? (2认同)