首页 > 解决方案 > 在 Jpa 中让服务器端分页查询聚合 sql 的最佳方法是什么?

问题描述

嗨,我想要实现的是获取 Page 的返回结果,结果进入 DTO 并作为 Pageable 请求。我该如何正确地做到这一点?

我找到了几种方式,但我不确定也不太舒服。我每次都尝试使用 QueryDsl 方式,但是当使用 sum() 和 group By 多列这样的聚合函数时,它有“计数”限制,现在将在我的存储库中编写带有 @Query() 注释的 nativeQuery,看起来像这样:

    @Query(name = "find_stock_total", nativeQuery = true)
    Page<StockTotalResponseDto> findStockTotalRsMap(Pageable pageable);

然后在我的实体类中,我必须编写@NamedNativeQueries 并使用@SqlResultSetMappings 对其进行映射,这是我的编写方式:

@NamedNativeQueries({
        @NamedNativeQuery(
                name = "find_stock_total",
                query = "SELECT product_id, product_code, sum(qty) FROM "book_stock"
    where warehouse_code = 'GBKTJKT1' and product_code in('MCM-508','TL-101') and branch_code = 'JKT' and branch_id = '1'
    GROUP BY product_id, product_code",
                resultSetMapping = "stock_total_response_dto"
        ),
        @NamedNativeQuery(
                name = "find_stock_total.count",
                query = "select count(*) from (
    SELECT product_id, product_code, sum(qty) FROM "book_stock"
    where warehouse_code = 'GBKTJKT1' and product_code in('MCM-508','TL-101') and branch_code = 'JKT' and branch_id = '1'
    GROUP BY product_id, product_code
) as count"
        )
})
@SqlResultSetMappings({
        @SqlResultSetMapping(
                name = "stock_total_response_dto",
                classes = @ConstructorResult(
                        targetClass = StockTotalResponseDto.class,
                        columns = {
                                @ColumnResult(name = "product_id", type = String.class),
                                @ColumnResult(name = "product_code", type = String.class),
                                @ColumnResult(name = "sum", type = BigInteger.class)
                        }
                )
        ),
        @SqlResultSetMapping(
                name = "stock_total_response_dto.count",
                columns = @ColumnResult(name = "count")
        )
})
@Entity

我将不得不在 @Entity 类中编写 sql 字符串,并且我不能使用 Pageable 提供的 Sort 并且我必须编写额外的 Count 查询。我想使用 Pageable Sort 来对我的数据进行排序。有没有另一种方法可以以更好的方式或现代方式编写类似的东西?也许有人可以提供“标准”方式或者还有另一种 Jpa 方式?或者比这更好的东西?

标签: javahibernatejpaspring-data-jpa

解决方案


您应该检查Blaze-Persistence必须提供哪些工作在 JPA/Hibernate 之上并且还与 spring-data-jpa 集成,这使您可以将它用作 spring-data-jpa 正常工作的替代品.

它正确支持聚合函数(也适用于计数查询),支持键集分页等等。查看有关 Spring Data 集成的文档:https ://persistence.blazebit.com/documentation/entity-view/manual/en_US/#spring-data-integration


推荐阅读