在 JPA 查询中转义冒号字符 ':'

问题描述 投票:0回答:4

我正在尝试通过使用“:”字符的 JPA 运行本机查询。特定实例在查询中使用 MySQL 用户变量:

SELECT foo, bar, baz, 
    @rownum:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    := foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc 

JPA 代码:

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();

但是,这给了我一个例外,即不允许在“:”后面添加空格。我尝试过用反斜杠转义它们,我尝试过通过将它们加倍来转义它们。有没有办法真正做到这一点,或者我可以吗?

mysql jpa jpql
4个回答
90
投票

在本机 JPA 查询中使用 postgresql json 函数时,我遇到了类似的经历。

select * from component where data ::json ->> ?1 = ?2

JPA 将抛出错误,表明我尚未设置命名参数:json。

解决方案:

"select * from component where data \\:\\:json ->> ?1 = ?2"

1
投票

我不知道在查询中转义冒号字符的标准方法,该字符显然被解释为命名参数前缀,从而使查询解析器感到困惑。

我的建议是如果可能的话创建并使用 SQL 函数。根据您的提供商的不同,可能还有其他选项(例如使用另一个字符并在拦截器中用

:
替换所选字符),但至少前面的建议将使您的 JPA 代码在提供商之间保持可移植性。

PS:如果您使用 Hibernate,HHH-1237 上附有一个非常旧的补丁。

更新: JPA 1.0 规范中有一个关于命名参数和本机查询的“有趣”段落:

3.6.3 命名参数

命名参数是一个标识符 以“:”符号为前缀。 命名参数区分大小写。

命名参数遵循以下规则 第 4.4.1 节中定义的标识符。 命名参数的使用适用于Java Persistence查询 语言,并且没有定义 原生查询。仅限位置 参数绑定可以便携使用 用于本机查询。

传递给的参数名称

setParameter
Query
的方法 API 不包含“:”前缀。

这不会真正帮助您,但您的情况强烈暗示本机查询中的“:”甚至不应该被考虑(至少没有办法逃避它或禁用它检测)。


0
投票

我在使用 hibernate-5.6.15.Final 时遇到了同样的问题,经过一番调试后,我发现在本机查询中转义 : 字符的方法是添加另一个 : 字符。

你可以尝试:

SELECT foo, bar, baz, 
    @rownum::= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    ::= foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc 

-1
投票

试试这个:

String query =
"SELECT foo, bar, baz, 
    @rownum \\\\:= if (@id = foo, @rownum+1, 1) as rownum, 
    @id    \\\\:= foo                         as rep_id 
FROM 
    foo_table 
ORDER BY 
    foo, 
    bar desc  -- escape='\' ";

Query q = getEntityManager().createNativeQuery(query, SomeClass.class);
return q.getResultList();
© www.soinside.com 2019 - 2024. All rights reserved.