哪一层最适合Java DTO的映射器,服务层或控制器层?

时间:2018-04-28 19:58:00

标签: java spring spring-transactions dto

最近我开始考虑@Transactional及其工作方式和性能,我有一个项目,我使用spring事务,所以我有这样的代码:

@Transactional
public PageableProductsDTO getUsersProducts(String userName, Pageable page) {
    PageRequest pageRequest = PageRequest.of(page.getPageNumber(), page.getPageSize(), Sort.Direction.DESC, "createdAt");
    Page<Product> pagebelProductsByUser = productRepository.findProductsByUser(userService.getUser(userName), pageRequest);
    Page<ProductDetailsDto> productDtos = pagebelProductsByUser.map(source -> {
        ProductDetails productDetails = source.getProductDetails();
        return new ProductDetailsDto(productDetails.getBarcode(), productDetails.getName(), productDetails.getPrice());
    });
    return new PageableProductsDTO(productDtos);
}

正如您所看到的,在上面的方法中,我从db获取产品,然后将产品映射到 PageableProductsDTO ,我怀疑我是否做得对,因为可能dto映射应该是在控制器层完成?而且似乎在服务层中进行这样的映射会延长交易本身的时间,我的意思是,从性能的角度来看,它可能并不好?

1 个答案:

答案 0 :(得分:1)

没有通用的解决方案,只有最适合你的解决方案。这不是关于DTO是模式还是反模式,它是关于你是否需要它们......以及为什么

问题的一部分是您是否应该在 controller service 层中重新打包数据。这完全取决于您是否引入了DTO来分离应用程序层的数据和业务逻辑 OR 您引入了DTO来重新打包将返回给客户端的数据(可能删除一些私有属性)(如果是这种情况,控制器应该开展业务)。

虽然在这种情况下性能影响可以忽略不计,但你应该 1 在单独的方法中移动从DB加载数据的逻辑,并将一个 2 标记为Transactional。

1 方法的分离将允许您重新使用从服务层内的DB加载数据的代码,而无需将数据重新打包回实体。

2 只要您想在执行db load后提交事务,这将是一个很好的模式。如果您想重新使用从DB加载数据的方法,请考虑其他用例,如果您想延长提交时间。