HQL检查列表大小在@param中传递

时间:2019-01-04 14:53:53

标签: java hibernate spring-data-jpa spring-data hql

是否可以检查util.List的大小?例如,是否为空?

我尝试了以下查询,并生成了一条消息QuerySyntaxException的{​​{1}}

??? is not mapped

1 个答案:

答案 0 :(得分:0)

正如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()
                );
            }

*注意:我的代码有点简化,不符合生产环境标准。我只想为那些遇到相同问题的人提供一个小例子。