如何检查collection参数在hql中是否为空?

How to check if a collection parameter is null in hql?

那么如何检查collection在HQL中是否为空?简单示例:

select * from Book book where title in (:titles)

所以如果 titles 是单个变量,我可以做到

select * from Book book where (:titles is null or title in (:titles))

但是如果 titles 是 list/collection 怎么办?

select * from Book book where (:titles is null or title in (:titles))

如果标题是列表,这将不起作用。经过激烈的搜索,我尝试了 is empty, size, and exists 函数,我也尝试了 (:titles) is null 选项。

None以上作品。我知道有一种写不同查询的硬编码方式取决于标题列表的状态,如果它是空的,一个查询,如果它是空的,另一个查询。但这会产生很多类似的 HQL 查询,但会有微小的变化。而且我的用例没有更多列表需要考虑,因此不需要。

我的问题是,是否可以直接在 HQL 中进行检查?

:titles 是一个列表。
你想搜索有论文 "titles" 的书籍。

用户,

  • 可能有 select 个头衔
  • 可能 select 编辑了多个标题
  • 或者可能select根本没有标题

因此此列表可能为空,其中可能包含一个或多个元素。

无论如何,您将使用 Query.setParameterList(),以便将标题 collection 传递到查询中,如 this answer 中所述。

现在,如果您尝试传递的参数可能为 null,则您不想使用 set 方法。毕竟我们在这里讨论的是Java。

因此,您需要检查此列表是否为空。
此外,如果用户 selected 的标题列表为空,则您不希望休眠检查是否为空。
您还需要只有一个查询,不需要多个查询。

执行此操作的方法是使用查询构建器。
有很多方法可以实现这种方法。但总的来说,你的想法是

  • 要么使用专门用于此类工作的框架,例如 Querydsl,check here
  • 或者您简单地使用 StringBuilder 构建查询的 select、from 和 where 子句,例如:

    Map<String,Object> params = new HashMap<String,Object>();
    StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.append(" from Book book ");
    if(!titlesList.isEmpty()){
        queryBuilder.append(" where book.title in (:titles) ");
        params.put("titles", titlesList);
    }
    Query query = entityManager.createQuery(queryBuilder.toString());
    for ( Map.Entry<String,Object>; param : params.entrySet()) {
        if(param instanceof Collection<?>){
            query.setParameterList(param.getKey(),param.getValue());
        }
        //if param is of type String then query.setString etc. 
        //else setParameter, you get the idea, use the docs
    }
    List<Book> results = (List<Book>) query.list();