那么如何检查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中进行检查吗?
答案 0 :(得分:0)
:titles
是一个列表。
您要搜索具有论文“标题”的书籍。
用户
因此,此列表可能为空,其中可能包含一个或多个元素。
无论如何,您都将使用Query.setParameterList()
,以将标题集合传递到查询中,如this answer中所述。
现在,如果您要传递的参数可能为null,那么您就不想使用set方法。毕竟,我们在这里谈论的是Java。
因此,您需要检查此列表是否为空。
另外,您也不想让休眠检查用户选择的标题列表是否为空。
您还只需要一个查询,就不需要多个查询。
执行此操作的方法是使用查询生成器。
有很多方法可以实现这种方法。但总的来说,想法是你
或者您可以简单地使用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();