[英]How to get Page as result in Querydsl query with fetch or fetchResults properly?
嗨,我想在这里实现的是,我想将 Pageable 数据提交到 QueryDsl 查询中并将结果作为 Page,我该如何正确地做到这一点? 这是我到目前为止所做的:
这是我的 controller:
@PostMapping("/view-latest-stock-by-product-codes")
public ResponseEntity<RequestResponseDTO<Page<StockAkhirResponseDto>>> findStockByProductCodes(
@RequestBody StockViewByProductCodesDto request) {
Page<StockAkhirResponseDto> stockAkhir = stockService.findByBulkProduct(request);
return ResponseEntity.ok(new RequestResponseDTO<>(PESAN_TAMPIL_BERHASIL, stockAkhir));
}
在我的 controller 我提交 StockViewByProductCodesDto 看起来像这样:
@Data
public class StockViewByProductCodesDto implements Serializable {
private static final long serialVersionUID = -2530161364843162467L;
@Schema(description = "Kode gudang yang ingin di tampilkan", example = "GBKTJKT1", required = true)
private String warehouseCode;
@Schema(description = "id dari sebuah branch", example = "1", required = true)
private Long branchId;
@Schema(description = "Kode Branch", example = "JKT", required = true)
private String branchCode;
@Schema(description = "Kode Product yang merupakan kode yang di ambil dari master product", example = "[\"MCM-508\",\"TL-101\"]", required = true)
private List<String> productCodes;
@Schema(description = "Size of row per page", example = "15", required = true)
@NotNull
private int size;
@Schema(description = "Page number", example = "1", required = true)
@NotNull
private int page;
@Schema(description = "Sort by", example = "id", required = false)
private String sort;
}
这是我的服务:
public Page<StockAkhirResponseDto> findByBulkProduct(StockViewByProductCodesDto request) {
String warehouseCode = request.getWarehouseCode();
Long branchId = request.getBranchId();
String branchCode = request.getBranchCode();
List<String> productCodes = request.getProductCodes();
Set<String> productCodesSet = new HashSet<String>(productCodes);
Pageable pageable = PageUtils.pageableUtils(request);
Page<StockAkhirResponseDto> stockAkhir = iStockQdslRepository.findBulkStockAkhirPage(warehouseCode, branchId, branchCode, productCodesSet, pageable);
return stockAkhir;
}
如您所见,我使用 PageUtils.pageableUtils(request) 提取可分页信息,这是我的 pageableUtils function 看起来像:
public static Pageable pageableUtils(RequestKeyword request) {
int page = 0;
int size = 20;
if (request.getPage() > 0) {
page = request.getPage() - 1;
}
if (request.getSize() > 0) {
size = request.getSize();
}
if (!request.getSort().isEmpty()) {
return PageRequest.of(page, size, Sort.by(request.getSort()).descending());
} else {
return PageRequest.of(page, size);
}
}
获得 Pageable 数据后,我将其提交到我的存储库中,如下所示:
public Page<StockAkhirResponseDto> findBulkStockAkhirPage(String warehouseCode, Long branchId, String branchCode,
Set<String> productCodes, Pageable pageable) {
JPQLQuery<Tuple> query = new JPAQuery<>(em);
long offset = pageable.getOffset();
long limit = pageable.getPageSize();
QStock qStock = QStock.stock;
NumberExpression<Integer> totalQty = qStock.qty.sum().intValue();
query = query.select(qStock.productId, qStock.productCode, totalQty).from(qStock)
.where(qStock.warehouseCode.eq(warehouseCode), qStock.productCode.in(productCodes),
qStock.branchCode.eq(branchCode), qStock.branchId.eq(branchId))
.groupBy(qStock.productId, qStock.productCode);
query.limit(limit);
query.offset(offset);
QueryResults<Tuple> result = query.fetchResults();
long total = result.getTotal();
List<Tuple> rows = result.getResults();
List<StockAkhirResponseDto> stockAkhirDto = rows.stream()
.map(t -> new StockAkhirResponseDto(t.get(0, Long.class), t.get(1, String.class), t.get(2, Integer.class)))
.collect(Collectors.toList());
return new PageImpl<>(stockAkhirDto, pageable, total);
}
查看我的存储库并且我能够运行我的项目时,我的编辑器中没有错误,但是当我执行我的存储库 function 时,我收到了这个错误:
“org.hibernate.hql.internal.ast.QuerySyntaxException:期待关闭,在第 1 行,第 38 列附近找到',' [选择计数(不同的 stock.productId,stock.productCode,stock.warehouseId,stock.warehouseCode,stock.branchCode , stock.branchId)\n来自 com.bit.microservices.b2b.warehouse.entity.Stock stock\n其中 stock.warehouseCode =?1 and stock.productCode in?2 and stock.branchCode =?3 and stock.branchId =?4 ]; 嵌套异常是 java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: 期待 CLOSE,在第 1 行,第 38 列附近找到',' .warehouseId、stock.warehouseCode、stock.branchCode、stock.branchId)\n来自 com.bit.microservices.b2b.warehouse.entity.Stock stock\n其中 stock.warehouseCode =?1 和 stock.productCode in?2 和 stock.branchCode =?3 和 stock.branch ID =?4]"
问题就在这里,在这一行:
QueryResults<Tuple> result = query.fetchResults();
当我执行该行时,它给了我该错误,我尝试获取 fetchResult,因为我想获取总数的 .getTotal()。
但如果我使用.fetch() 执行查询,它工作正常,如下所示:
List<StockAkhirResponseDto> stockAkhirDto = query.fetch()
我的 sql 结果正确执行,我在这里错过了什么? 我如何正确获得页面结果?
您的问题可能与开放的 QueryDSL问题有关。 记录的问题与fetchCount
的使用有关,但我认为很可能也是您的情况。
考虑上述问题中的以下评论:
fetchCount()
使用一个COUNT
function,它是一个聚合 function。 您的查询已经具有聚合函数。 您不能聚合聚合函数,除非使用子查询(在 JPA 中不可用)。 因此,无法支持此用例。
该问题也提供了一个临时解决方案。
基本上,这个想法是能够通过在初始 select 上创建一个语句来执行COUNT
。 AFAIK QueryDsl 不可能,这就是为什么在指定的解决方法中他们访问 Hibernate 提供的下划线机制。
也许,您可以尝试避免限制的另一件事是为您的查询创建一个数据库视图,在其上创建相应的 QueryDsl 对象,并使用这些对象执行实际计算。 我知道这不是一个理想的解决方案,但它会绕过这个当前的 QueryDsl 限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.