java - 如何注册 SQL 函数,以便您可以使用 JPA 和 Hibernate 在 JPQL 或 HQL 查询中调用它们

标签 java mysql spring hibernate

我想在我的 HQL 查询中使用一个自定义函数,我在我的数据库中注册了一个函数,这是我的函数的 sql 代码:

BEGIN
DECLARE user_id_var VARCHAR(64);
    SELECT 
    e.username
FROM
   users e  where e.id=30 INTO user_id_var;   
    return user_id_var;
END

并将其注册为 MysqlCustomDilect 类:

public class MysqlCustomDilect extends MySQLDialect{

    public MysqlCustomDilect() {
        super();
        registerFunction("getActiveUser", new StandardSQLFunction("getActiveUser"));
}

}

并将此行添加到 hibernate.cfg.xml 文件中:

<property name="hibernate.dialect" value="myProject.common.MysqlCustomDilect" />

并在我的 dao 层中像这样调用它:

@Override
    public List<Entity> getAll() {
        Session session = getSession();
        String hql = " select e.id as id,function('getActiveUser') as name from " + domainClass.getName() + " e ";
        Query query=session.createQuery(hql);
        return query.list();

    }

但 hibernate 并不知道它并引发此错误:

unexpected token: function near line 1, column 18 [ from e.id as id,function('getActiveUser') ........

最佳答案

JPA 支持像这样调用用户定义的函数:

select i 
from Item i 
where function( 'substring', i.name, 1, 3 ) = 'abc'" )

首先,你的函数不完整,你只贴了函数体,没有贴函数名。

其次,你是连接字符串,所以你冒着 SQL Injection 的风险攻击。

第三,HQL格式错误:

来自 e.id

您如何从标识符中进行选择? FROM 子句应该改为列出一个实体。

因此,HQL最有可能是:

select e, function('getActiveUser',) as name
from MyEntity e

为什么要连接 domainClass.getName()?如果实体查询是动态的,请使用 Criteria API。

您还可以使用 MetadataBuilderContributor 注册函数:

public class SqlFunctionsMetadataBuilderContributor
        implements MetadataBuilderContributor {
         
    @Override
    public void contribute(MetadataBuilder metadataBuilder) {
        metadataBuilder.applySqlFunction(
            "group_concat",
            new StandardSQLFunction(
                "getActiveUsers",
                StandardBasicTypes.STRING
            )
        );
    }
}

并通过 hibernate.metadata_builder_contributor 向 Hibernate 提供自定义 MetadataBuilderContributor配置属性:

<property>
    name="hibernate.metadata_builder_contributor"
    value="com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor"
</property>

关于java - 如何注册 SQL 函数,以便您可以使用 JPA 和 Hibernate 在 JPQL 或 HQL 查询中调用它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40420794/

相关文章:

java - Hibernate 无法创建表 hibernate_sequences

php - MySQL SHA() 不起作用

java - Spring:为静态属性注入(inject)bean时出现NullPointerException

Java 上边界图形

java - Hibernate Envers 不使用 SpringMVC 配置在审计表中写入任何内容

PHP 在带有 PDO 绑定(bind)的 mysql 查询中使用数组

java - @PreDestroy 没有被调用以用于 Runnable

java - 当页面从浏览缓存加载时如何执行javascript?

JavaFX - 获取当前在 TextArea 中输入的单词

java - 抑制 SLF4J 多重绑定(bind) Gradle