如何使用JPA调用SQL本机函数,需要恒定参数



我尝试获取看起来像这样的查询:

select count(*) from somewhere group by DATEDIFF(week, '2010-01-01', creation_date);

我的问题是在功能调用上。我正在使用下面的Hibernate的JPA Criteriabuilder(CB)(root是我的某个地方):

cb.function("DATEDIFF", Integer.class, cb.literal("week"), cb.literal('2010-01-01'), root.<Date>get("creationDate")

生成的SQL是:

select count(*) from somewhere group by DATEDIFF(?, ?, creation_date);
- param1: 'week'
- param2: '2010-01-01'

哪个不起作用,因为第一个函数参数应该是常数而不是"?"。

我该如何像这样注入这个常数参数(没有引号,不是参数)?

谢谢

在这种情况下我的对象类似:

@Entity
public class Somewhere {
    @Id
    private Long id;
    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate;
    // Getters and setters
}

基于基督教评论,解决方案实际上很容易实现。

SQL Server方言带有新功能'WeekDiff':

import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.type.StandardBasicTypes;
public class ExtendedSqlServerDialect extends SQLServerDialect {
    public ExtendedSqlServerDialect() {
        registerFunction("weekdiff", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "datediff(week, ?2, ?1)"));
    }
}

然后,只需要要求Hibernate使用此方言(我正在使用Spring Boot)。

application.yml

spring.jpa.properties.hibernate.dialect: com.xxx.dialect.ExtendedSqlServerDialect

代码示例我在哪里使用:

CriteriaBuilder cb /* = ... */;
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<Upload> root = query.from(Somewhere.class);
query.groupBy(cb.function("weekdiff",
    Integer.class,
    root.get("creationDate"),
    cb.parameter(String.class, "refDate")).alias("week")
);

并且由于我在单元测试上使用了HSQLDB,因此在这里对应 HSQLDB方言

import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.type.StandardBasicTypes;
public class ExtendedHsqlDialect extends SQLServerDialect {
    public ExtendedHsqlDialect() {
        registerFunction("weekdiff", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "truncate(datediff('day', ?2, ?1) / 7)"));
    }
}

不幸的是,我无法通过子句在组上使用此功能(请参阅"为什么约会订单"使用JPA在SQL Server上提出异常?)

最新更新