如何在 JPQL 或 HQL 查询中使用 MySQL CONVERT_TZ 函数

Hip*_*ray 4 java timezone timestamp hibernate hql

目前,我有表在MySQL其中有一个数据库startDateendDate这两者都是timestamps。这与使用 hibernate 的代码相关联。

我可以使用以下 HQL 返回这些

SELECT startDate, endDate FROM Reservation where id = :id
Run Code Online (Sandbox Code Playgroud)

我想做的是根据给定的时区返回这些日期。我知道 MySQL 有一个函数CONVERT_TZ可以根据给定的时区返回日期,我想知道 HQL 是否有类似的函数?

我知道 HQL 有一个TIMESTAMP_WITH_ZONE函数,但是当我需要指定时区时它使用本地时区,可以这样做吗?

Vla*_*cea 5

自 Hibernate ORM 5.2.18

从 5.2.18 开始,您可以通过以下方式注册 SQL 函数MetadataBuilderContributor

public class SqlFunctionsMetadataBuilderContributor 
        implements MetadataBuilderContributor {
         
    @Override
    public void contribute(MetadataBuilder metadataBuilder) {
        metadataBuilder.applySqlFunction(
            "convert_tz", 
            new StandardSQLFunction( "convert_tz", StandardBasicTypes.TIMESTAMP )
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

Ans 只需MetadataBuilderContributor通过hibernate.metadata_builder_contributor配置属性提供:

<property>
    name="hibernate.metadata_builder_contributor" 
    value="com.vladmihalcea.book.hpjp.hibernate.query.function.SqlFunctionsMetadataBuilderContributor"
</property>
Run Code Online (Sandbox Code Playgroud)

在 Hibernate ORM 5.2.18 之前

或者,如果您使用 Hibernate 本机机制进行引导,则可以在构建Hibernate 用户指南MetadataBuilder中所述的时候注册该函数。

注册 SQL 函数的一种非常常见但幼稚的方法是覆盖 MySQL 方言并像这样注册新函数:

class CustomMySQLDialect extends MySQL5InnoDBDialect {
    public CustomMySQLDialect() {
        super();
        registerFunction( "convert_tz", new StandardSQLFunction( "convert_tz", StandardBasicTypes.TIMESTAMP ) );
    }

}
Run Code Online (Sandbox Code Playgroud)

配置 Hibernate 以使用新方言:

<property>
    name="hibernate.metadata_builder_contributor" 
    value="com.vladmihalcea.book.hpjp.hibernate.CustomMySQLDialect"
</property>
Run Code Online (Sandbox Code Playgroud)