【问题标题】:JPQL substring with regex带有正则表达式的 JPQL 子字符串
【发布时间】:2017-02-15 00:47:52
【问题描述】:

我有一个表格文件夹,其中包含类似的行

id  |  path
1   | root
2   | root.first
3   | root.second
4   | root.first.child1
5   | root.first.child1.grandchild1
6   | root.first.child2

我只需要获取路径为 root.first.child1 和 root.first.child2 而不是 root.first.child1.grandchild1 的行 我可以使用像

这样的子字符串将其作为本机查询来实现
select path from folder 
where substring (path from '((root.first\.)[^\.]+)?') is not null;

我正在寻找 JPQL 中的等效查询。 JPQL 中的子字符串似乎带有索引和长度,但我无法获得关于它是否可以与正则表达式模式一起使用的参考。

【问题讨论】:

  • 根据您的数据库,您可能不需要使用子字符串。 MySQL 有一个基本的正则表达式支持,您可以使用 WHERE path REGEXP '^root\.first\.child[123]$',PostgreSQL 使用简写 ~ 表示区分大小写的 POSIX 正则表达式,~* 表示不区分大小写,并且还支持 SQL 标准 SIMILAR TO。只需原生并享受细微的性能调整。
  • JPQL 有 LIKE 是最近的东西。除此之外,您还可以使用 JPQL "FUNCTION" 调用本机 SQL 函数
  • 谢谢,postgres 和 oracle 将支持该查询,因此使用 db 特定语法对我没有帮助。所以天真的查询是选项。
  • 我刚刚检查了 JPA 文档,他们将 SUBSTRING(string, start[, end]) 作为子字符串操作。 Oracle 似乎没有标准的SIMILAR TO 运算符,所以也许你应该在每个数据库上使用CREATE FUNCTION 来为PG 中的~ 和Oracle 中的REGEXP_LIKE 创建一个通用代理。那将是一次性操作对彼此而言。从那时起,它们似乎足以满足您的需求。

标签: java sql regex jpa jpql


【解决方案1】:

似乎没有通用的解决方案,但是您可以在 Postgres 中创建一个 polyfill 函数,这将允许您在两个服务器上使用 POSIX 正则表达式。

CREATE OR REPLACE FUNCTION REGEXP_LIKE (IN input text, IN pattern text, IN flags varchar DEFAULT '')
RETURNS BOOLEAN
IMMUTABLE
COST 0.013
AS $$
BEGIN
    RETURN array_length(regexp_matches(input, pattern, flags), 1) > 0;
END;
$$ LANGUAGE plpgsql;

成本是用真实数据粗略衡量的。

有了这个,您可以在 Oracle 和 PostgreSQL 中几乎完全相同地使用 REGEXP_LIKEcim 似乎是他们都同意应该如何工作的唯一标志。

【讨论】:

    猜你喜欢
    • 2013-10-21
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多