如何检查hql中的collection参数是否为null?

gam*_* wu 7 hibernate hql

那么如何检查hql中的集合是否为null?简单的例子:

select * from Book book where title in (:titles)
Run Code Online (Sandbox Code Playgroud)

因此,如果标题是单一的可用,我可以做到

select * from Book book where (:titles is null or title in (:titles))
Run Code Online (Sandbox Code Playgroud)

但是如果title是列表/集合呢?

select * from Book book where (:titles is null or title in (:titles))
Run Code Online (Sandbox Code Playgroud)

如果title是一个列表,这将不起作用.在强烈搜索之后,我尝试了空,大小和存在函数,我也试过(:titles)是null选项.

以上都不是.我知道有一种硬编码方式,即编写不同的查询取决于标题列表的状态,如果它是null,一个查询,如果它是null,则另一个查询.但这会产生很多类似的hql查询,只有很小的改动.我的用例中还有更多的列表需要考虑,因此不太理想.

我的问题是甚至可以直接在hql中进行检查吗?

Chr*_*pas -3

:titles是一个列表。
您想要搜索具有这些“标题”的书籍。

用户,

  • 可能选择了一个标题
  • 可能选择了多个标题
  • 或者可能根本没有选择任何标题

所以这个列表可能为空,其中可能有一个或多个元素。

在任何情况下,您都将使用Query.setParameterList(), 以便将标题集合传递到查询中,如本答案中所述。

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

因此,您需要的是检查该列表是否为空。
另外,您不希望休眠检查用户选择的标题列表是否为空。
您也只需要一个查询,不需要多个查询。

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

  • 要么使用专门针对此类工作的框架,例如 Querydsl,请查看此处
  • 或者您可以简单地使用 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();
    
    Run Code Online (Sandbox Code Playgroud)