哪一层最适合JavaDTO的映射器、服务层还是控制器层?

哪一层最适合JavaDTO的映射器、服务层还是控制器层?,java,spring,spring-transactions,dto,Java,Spring,Spring Transactions,Dto,最近我开始思考@Transactional及其工作原理和性能,我有一个使用spring事务的项目,所以我有这样的代码: @Transactional public PageableProductsDTO getUsersProducts(String userName, Pageable page) { PageRequest pageRequest = PageRequest.of(page.getPageNumber(), page.getPageSize(), Sort.Direc

最近我开始思考@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获取产品,然后将产品映射到PageableProductsTo,我怀疑我是否正确,因为dto映射可能应该在控制器层完成?而且,在服务层进行这样的映射似乎会延长事务本身所花费的时间,我的意思是,从性能的角度来看,这可能不好?

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

问题的一部分是您是否应该在控制器或服务层中重新打包数据。这完全取决于是否引入DTO来分离应用程序层的数据和业务逻辑,或者是否引入DTO来重新打包数据,可能会删除一些将返回给客户机的私有属性。如果是后者,则controller应该执行该业务

虽然在这种情况下性能影响看起来可以忽略不计,但您应该在单独的方法中移动从数据库加载数据的逻辑,并将其标记为事务性的

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

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