1

我正在构建一个查询,我想将集合作为参数传递:

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) )

但它似乎都不起作用。如何解决此问题并仅在列表不为空时检查项目名称是否在列表中?

4

2 回答 2

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);
于 2012-11-26T22:25:52.070 回答
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();
于 2012-11-26T21:59:56.323 回答