【问题标题】:Does JPQL support the use of a boolean result in another expression?JPQL 是否支持在另一个表达式中使用布尔结果?
【发布时间】:2022-01-12 06:41:47
【问题描述】:

我正在尝试编写查询来支持搜索 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'));

【问题讨论】:

  • 你应该在你的java程序中而不是在查询中编写这个逻辑
  • @Jens 这是一个有很多参数的大查询。 JPA 支持将存储库直接公开为 REST 端点。你是说 Spring Data JPA 中的整个特性都错了吗?
  • 您似乎暗示不应使用@RestResource。 docs.spring.io/spring-data/rest/docs/current/api/org/…
  • @Jens 如果您甚至可以提供代码替代方案,那就太好了。在这种情况下,我没有得到其他选择。

标签: java hibernate jpa spring-data jpql


【解决方案1】:

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

实际上,您最好有两个不同的查询:一个用于“=”,另一个用于“”。

总的来说,这感觉像是 JPA 标准中的一个遗漏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 2011-12-13
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多