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

时间:2018-07-16 21:54:23

标签: hibernate hql

那么如何检查HQL中的集合是否为空?简单示例:

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

如果标题是一个变量,我可以做

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

但是,如果标题是列表/集合怎么办?

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

如果标题是列表,则此方法不起作用。经过激烈的搜索,我尝试了为空,大小和存在函数,我也尝试了(:titles)为null选项。

以上所有方法均无效。我知道有一种硬编码的方式来编写不同的查询,具体取决于标题列表的状态,如果为null,则执行一个查询,如果为null,则进行另一查询。但这将产生很多类似的HQL查询,但会有一些微小的变化。而且我的用例还有更多要考虑的列表,所以这是不希望的。

我的问题是什至有可能直接在HQL中进行检查吗?

1 个答案:

答案 0 :(得分:0)

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

用户

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

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

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

现在,如果您要传递的参数可能为null,那么您就不想使用set方法。毕竟,我们在这里谈论的是Java。

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

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

  • 要么使用专门用于这类工作的框架,例如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();