我正在构建一个查询,我想将一个集合作为参数传递:
List<String> items = new LinkedList();
//adding optional items
Query query = s.getNamedQuery("myQueryName").setParameterList("item", items);
我的查询如下:
SELECT i from Item i
//... not important things
WHERE ( i.name in (:item) )
但我想让它成为可选项,因此项目列表可能为空。但是当它空了,我得到一个例外:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree
所以我尝试使用一些函数,如:
SELECT i from Item i
//... not important things
WHERE ( (:item) is null or i.name in (:item) )
SELECT i from Item i
//... not important things
WHERE ( (:item) is empty or i.name in (:item) )
SELECT i from Item i
//... not important things
WHERE ( size(:item)=0 or i.name in (:item) )
但似乎没有任何效果。如果列表不为空,我该如何解决此问题并检查项目名称是否在列表中?
答案 0 :(得分:3)
您可以在列表中添加一个您知道永远不会返回true的值。例如,假设您有一个整数列表,并且您想查看列表中是否包含ID。您可以在列表中添加“-1”,它应该按照您想要的方式工作。对于您的字符串示例,只需添加一个永不发生的随机字符串。
类似的东西:
List<String> items = new LinkedList();
items.add("**BLAHBLAH_YO_MAMMA_SO_SLEAZY_SHE_ALWAYS_RETURN_TRUE**");
//add optional items
Query query = s.getNamedQuery("myQueryName").setParameterList("item", items);
答案 1 :(得分:2)
那就是,恕我直言,SQL中的设计问题,当然也存在于HQL中,因为它直接转换为SQL。
在HQL中没有简单的解决方案可以解决这个问题。最简单,最有效的方法是在生成和执行查询之前检查列表。
在许多情况下,您只需要这样做:
if (items.isEmpty()) {
return Collections.emptyList();
}
在您的情况下,我会使用条件查询(或用于动态构建查询的其他API),并动态构建查询:
Criteria c = session.createCriteria(Item.class, i);
...
if (!items.isEmpty()) {
c.add(Restrictions.in("i.name", items));
}
return c.list();