首页 > 解决方案 > 如何在方法之前和之后从带有参数的函数在方言上注册函数?

问题描述

我正在尝试REGEXP在 H2 内存数据库上使用 MySQL 5.7 数据库中的函数运行 JPQL。我想使用相同的查询进行集成测试。

由于REGEXPH2 上不存在该函数,我正在尝试注册一个新函数以使其工作,REGEXP_LIKE而是使用 H2 函数(仅用于测试)。

我的查询是:

String sql = "select o1.id from order o1 where :url REGEXP o1.regex";

但我无法弄清楚注册函数的正确语法。我在下面尝试这样的事情,但我知道这是不正确的,因为我发现的所有示例都是用参数映射“正常”函数,但 REGEXP 使用的语法类似于:url REGEXP o1.regex而不是REGEXP(:url, o1.regex)

public class MyH2Dialect extends H2Dialect {

    public MyH2Dialect() {
        super();
        registerFunction("REGEXP", 
            new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "REGEXP_LIKE(?1, ?2, 'i')"));
    }

}

自然 JPQL 无法识别该功能:

引起:org.hibernate.hql.internal.ast.QuerySyntaxException:意外令牌:REGEXP

我想象我需要做这样的事情(伪代码):

registerFunction("?1 REGEXP ?2", 
    new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "REGEXP_LIKE(?1, ?2, 'i')"));

有任何想法吗?

标签: javamysqlhibernateh2jpql

解决方案


我正在尝试在 H2 内存数据库上使用 MySQL 5.7 数据库中的 REGEXP 函数运行 JPQL。

好吧,我无法注册该功能,但我能够REGEXP在 H2 上运行该功能。

我的错误是尝试使用 JPQL 而不是 Native Query 来使其运行。

em.createNativeQuery(sql);

当我在 H2 数据库上运行在 MySQL 上使用的相同查询时,SQL 按预期工作。所以,我不需要注册这个功能。我无法理解这是可能的,因为 H2 文档没有提及REGEXP功能,但SO 上的另一个问题提到该功能存在。

我发现的另一种可能性(在使上述解决方案生效之前)是将 MySQL 升级到 8.x 版本,因为他们创建了一个名为的新函数,该函数与 H2中的函数REGEXP_LIKE具有几乎相同的签名。REGEXP_LIKE


推荐阅读