查询DSL Trunc日期

问题描述 投票:2回答:1

我需要在查询之间使用querydsl进行只有日期比较而没有时间戳的查询。

QueryDsl。

Date startDate=
Date endDate=
QEmp qEmp=

BooleanExpression empExp = qEmp.id.dob.between(startDate, endDate);

表:

select dob from employee where eid=2;
10-MAR-07 12.00.00.000000000 AM

SQL查询dob之间。

select * from employee where dob between trunc(start date) and trunc(end dat)

这可以找到开始日期和结束日期之间的记录,但没有时间戳。我需要在QueryDSl中执行同样的内容。数据库是Oracle。

spring querydsl
1个回答
0
投票

不幸的是.., DATE_TRUNC 中没有定义的函数。JPQL 因此,没有一个JPA实现--比如Hibernate--支持这个函数,但是可以在各种JPA实现中注册为自定义函数,然后你可以使用自定义的QueryDSL集。

DATE_TRUNC 然而,可以在各种JPA实现中注册为自定义函数,然后你可以使用一组自定义的QueryDSL--------------。Templates 以包含对这些函数的处理。

例如,对于Hibernate。

public class DateTruncMetadataBuilderInitializer
        implements MetadataBuilderInitializer {
    @Override
    public void contribute(MetadataBuilder metadataBuilder,
            StandardServiceRegistry serviceRegistry) {
        metadataBuilder.applySqlFunction("DATE_TRUNC",
            new SQLFunctionTemplate(DateType.INSTANCE,
                "DATE_TRUNC(?1, ?2)"));
    }
}

你需要将这个类注册到一个叫作 META-INF/services/org.hibernate.boot.spi.MetadataBuilderInitializer.

更改后,您可以使用 DATE_TRUNC 在你的JPQLHQL查询中,像这样。

SELECT a FROM Entity a 
    WHERE a.dateField BETWEEN DATE_TRUNC('day', :start) AND DATE_TRUNC('day', :end)

现在你必须让这个函数能被QueryDSL使用。你可以通过声明一个自定义模板来实现。

public class MyTemplates extends JPQLTemplates {

    public MyTemplates() {
        add(DateTimeOps.TRUNC_DAY, "DATE_TRUNC('day', {0})");
    }

}

然后按如下方式使用它

new JPAQuery(entityManager, new MyTemplates()).from(entity)
    .select(Expressions.dateOperation(DateTimeOps.TRUNC_HOUR, dateExpression))

然而,有了Spring的集成,就会有 Templates 我想是比较难绑定到查询的。

或者,你可以研究一下 blaze-persistence-querydsl 扩展,它对JPQL中的日期时间操作有开箱即用的支持。

© www.soinside.com 2019 - 2024. All rights reserved.