正如 dbl 在他的评论中回答的那样,无法检查作为 @Param 传递的 List 的大小。
您正在使用 HQL,因此由于 JPQL 查询始终是有效的 HQL 查询,因此我想分享我的解决方案。
@Query("SELECT p FROM Product p "
+ "LEFT JOIN p.categories category "
+ "WHERE p.name LIKE CONCAT('%', :searchRequest, '%') "
+ "AND p.description LIKE CONCAT('%', :description, '%') "
+ "AND p.price BETWEEN :priceLow AND :priceHigh "
+ "AND p.archived = :archived "
+ "AND category.name IN :selectedCategories "
+ "GROUP BY p "
+ "HAVING SIZE(p.categories) >= :amountOfSelectedCategories"
)
Page<Product> findAllBySearchModel(
Pageable pageable,
@Param("searchRequest") String searchRequest,
@Param("description") String description,
@Param("priceLow") BigDecimal priceLow,
@Param("priceHigh") BigDecimal priceHigh,
@Param("archived") boolean archived,
@Param("selectedCategories") List<String> selectedCategories,
@Param("amountOfSelectedCategories") int amountOfSelectedCategories
);
由于 WHERE ... IN 子句总是使用 OR 条件,并且我想缩小搜索范围,因此我必须找到另一种方法来进一步限制我的结果。
因此,我需要传入列表的大小。
在 JPQL 中,您可以轻松使用 SIZE(),@Param 除外。
这导致了一个完整的解决方法,将我的列表的大小添加为一个额外的@Param。我还在我的服务层中检查了一个空列表。
if (!searchModel.getSelectedCategories().isEmpty()) {
return productService.findAllBySearchModel(
pageable,
searchModel.getSearchRequest(),
searchModel.getDescription(),
searchModel.getPriceLow(),
searchModel.getPriceHigh(),
searchModel.isArchivedView(),
searchModel.getSelectedCategories(),
searchModel.getSelectedCategories().size()
);
}
*注意:我的代码有点简化,不符合生产环境标准。我只是想为那些遇到同样问题的人提供一个小例子。