JPQL是否支持在另一个表达式中使用布尔结果



我正在尝试编写一个查询来支持搜索API。特别是对于标志searchDrafts——如果标志是true,我必须获得具有statusDRAFT的行,否则我必须获得除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'));
Jakarta Persistence 3.0规范中的JPQL语法不允许这样做。(我手头有3.0,但我没想到早期的版本会有所不同。(布尔比较对应于这个生产规则:
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是直接进入WHENWHEREHAVINGON子句的内容。这意味着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标准中的一个遗漏。

最新更新