我正在尝试使用QueryDSL计算平均日期差异.
我创建了一个小项目,以简化的方式演示我想要完成的任务(真正的查询要复杂得多,有大量的连接/ where/sort子句).我们有一个带有字段的Customer类birthDate,我们正在努力获得客户的平均年龄(以秒为单位).我们也想要最大年龄,但让我们关注这篇文章的平均值.
我尝试使用querydsl-jpa编写此查询,但它失败了一个模糊的错误:
java.lang.NullPointerException
at org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions$AvgFunction.determineJdbcTypeCode(StandardAnsiSqlAggregationFunctions.java:106)
at org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions$AvgFunction.render(StandardAnsiSqlAggregationFunctions.java:100)
at org.hibernate.hql.internal.ast.SqlGenerator.endFunctionTemplate(SqlGenerator.java:233)
[...]
Run Code Online (Sandbox Code Playgroud)
我也尝试过其他方法,比如使用NumberTemplate.create(Double.class, "{0} - {1}", DateExpression.currentDate(), customer.birthDate).avg(),但它没有返回正确的值.如果我们想要以秒为单位获得日期差异,似乎我们需要找到一些方法来调用特定于数据库的日期/时间差异函数,而不仅仅是使用减号.
遗憾的是,在JPQL中似乎不可能计算日期差异,所以我猜querydsl-jpa也有局限性.因此,我们必须编写本机SQL查询,或者找到一些hack来使QueryDsl生成的JPQL调用本机数据库函数.
JPA 2.1增加了对调用数据库函数的支持,但是存在一个问题:MySQL函数采用的形式TIMESTAMPDIFF(SECOND, '2012-06-06 13:13:55', '2012-06-06 15:20:18').如果第一个参数(SECOND)是一个String,它可能是可能的,但它似乎是对某种常量的引用,并且在第一个参数未引用的情况下生成JPQL似乎很复杂.
QueryDSL增加了对日期差异的支持,但似乎大多数代码都驻留在querydsl-sql项目中,所以我想知道我是否可以通过querydsl-jpa从中受益.
这是我的问题:
是否可以使用querydsl-jpa计算平均日期差异,让它可以使用JPA 2.1支持调用本机数据库函数(可能使用Expressions.numberTemplate())?或者我们被迫使用querydsl-sql?
如果我们不得不使用querydsl-SQL,我们如何产生既QCustomer与SCustomer?QCustomer目前使用插件"com.mysema.maven:apt-maven-plugin"从Customer实体生成.如果我理解正确,我必须使用不同的插件(com.querydsl:querydsl-maven-plugin)来生成SCustomer查询类型?
在查看querydsl-sql-example时,我没有看到任何实体类,所以我猜查询类型是由QueryDSL从数据库模式生成的?有没有办法从实体生成SCustomer查询类型,就像我们使用querydsl-jpa一样?
如果我们使用querydsl-sql,有没有办法在querydsl-sql查询中"重用"我们的querydsl-jpa谓词/ sorts/joins子句?或者我们是否必须使用特定于querydsl-sql的类复制该代码?
我也在考虑创建一个委托的数据库函数TIMESTAMPDIFF(SECOND, x, y),但它不是很便携......
我错过了什么吗?有没有更简单的方法来做我想做的事情?
使用模板表达式,您应该能够将任何自定义 JPQL 片段注入到 Querydsl 查询中。这应该回答你的第一个问题。
在同一个项目中使用 querydsl-jpa 和 querydsl-sql 是可能的,但会增加一些复杂性。
| 归档时间: |
|
| 查看次数: |
1137 次 |
| 最近记录: |