JPQL 是否支持在另一个表达式中使用布尔结果?
Does JPQL support the use of a boolean result in another expression?
我正在尝试编写一个查询来支持搜索 API。专门针对标志 searchDrafts
- 如果标志是 true
我必须获得带有 status
DRAFT
的行,否则我必须获得所有具有任何 [=15= 的行] 除了 DRAFT
.
在常规 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
是直接在 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
。
实际上,您最好有两种不同的查询:一种针对“=”,另一种针对“<>”。
总的来说,感觉像是JPA标准中的遗漏。
我正在尝试编写一个查询来支持搜索 API。专门针对标志 searchDrafts
- 如果标志是 true
我必须获得带有 status
DRAFT
的行,否则我必须获得所有具有任何 [=15= 的行] 除了 DRAFT
.
在常规 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
是直接在 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
。
实际上,您最好有两种不同的查询:一种针对“=”,另一种针对“<>”。
总的来说,感觉像是JPA标准中的遗漏。