HQL 中的存储过程

Stored procedures in HQL

如何在HQL中编写存储过程或函数?可能吗?我还没有找到任何相关信息。

问题是我的应用程序与多个数据库(Oracle、MSSQL、PostgreSQL)一起工作,我需要在查询中计算 Levenshtein 距离。我可以不为每个数据库编写 3 个本机 SQL 函数和查询吗?

您可以尝试在休眠方言中封装不同数据库中Levenshtein 函数名称之间的差异。下面我将提供一个 Oracle 和 PostgreSQL 的例子。 (我没有使用 MSSQL)

  1. 扩展的 Oracle 方言:
public class MyOracleDialect extends Oracle12cDialect
{
   public MyOracleDialect()
   {
      super();
      registerFunction( "levenshtein", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "UTL_MATCH.EDIT_DISTANCE(?1,?2)" ) );
   }
}
  1. 扩展的 PostgreSQL 方言:
public class MyPostgreSQLDialect extends PostgreSQL95Dialect
{
   public MyPostgreSQLDialect()
   {
      super();
      registerFunction( "levenshtein", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "levenshtein(?1, ?2)"));
   }
}
  1. 现在您可以在 HQL 中使用 levenshtein 函数了。
List<Integer> result = session.createQuery(
   "select levenshtein(word1, word2) from TestEntity",
   Integer.class
).getResultList();

P.S. 对于 PostgreSQL,我遇到了以下问题: 如果为特定模式安装了扩展 fuzzystrmatch TEST_SCHEMA:

SQL> create extension fuzzystrmatch;

那么你应该在连接中指定这个模式 url:

<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/postgres?currentSchema=TEST_SCHEMA</property>

否则会出现异常:

org.postgresql.util.PSQLException: ERROR: function levenshtein(character varying, character varying) does not exist. No function matches the given name and argument types. You might need to add explicit type casts.