我正在尝试编写一个查询来支持搜索API。特别是对于标志searchDrafts
——如果标志是true
,我必须获得具有status
DRAFT
的行,否则我必须获得除DRAFT
之外具有任何status
的所有行。
在常规SQL中,以下查询运行良好:
SELECT id, status
FROM records
where ((status = 'DRAFT') = :searchDrafts);
然而,JPQL中类似的东西不起作用:
SELECT r
FROM Records r
WHERE ((r.status = 'DRAFT') = :searchDrafts);
它给出了错误:
unexpected AST node: = near line 1, column nn
在JPQL中有什么方法可以在另一个表达式中使用布尔结果的值吗?
另一种选择是用更长的方式,但有点冗长。这在JPQL:中运行良好
SELECT id, status
FROM records
where (:searchDrafts=true AND (status = 'DRAFT'))
or (:searchDrafts=false AND (status != 'DRAFT'));
comparison_expression ::=
...
boolean_expression {= | <>} {boolean_expression | all_or_any_expression} |
...
那么comparison_expression
只作为conditional_expression
生成规则的一部分:
conditional_expression ::= conditional_term | conditional_expression OR conditional_term
conditional_term ::= conditional_factor | conditional_term AND conditional_factor
conditional_factor ::= [NOT] conditional_primary
conditional_primary ::= simple_cond_expression | (conditional_expression)
simple_cond_expression ::=
comparison_expression |
...
conditional_expression
是直接进入WHEN
、WHERE
、HAVING
和ON
子句的内容。这意味着comparison_expression
不能是boolean_expression
。
除了AND
的解决方案外,这个似乎也很有效:
SELECT r
FROM Records r
WHERE CASE WHEN r.status = 'DRAFT' THEN TRUE ELSE FALSE END = :searchDrafts;
它很难看,但它确实将conditional_expression
转换为boolean_expression
。
在实践中,您最好有两个不同的查询:一个用于"="另一个用于"<gt&";。
总的来说,这感觉像是JPA标准中的一个遗漏。