相关疑难解决方法(0)

使用querydsl-jpa/querydsl-sql的平均日期差异

我正在尝试使用QueryDSL计算平均日期差异.

我创建了一个小项目,以简化的方式演示我想要完成的任务(真正的查询要复杂得多,有大量的连接/ where/sort子句).我们有一个带有字段的CustomerbirthDate,我们正在努力获得客户的平均年龄(以秒为单位).我们也想要最大年龄,但让我们关注这篇文章的平均值.

我尝试使用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从中受益.

这是我的问题:

  1. 是否可以使用querydsl-jpa计算平均日期差异,让它可以使用JPA 2.1支持调用本机数据库函数(可能使用Expressions.numberTemplate())?或者我们被迫使用querydsl-sql?

  2. 如果我们不得不使用querydsl-SQL,我们如何产生既QCustomerSCustomerQCustomer目前使用插件"com.mysema.maven:apt-maven-plugin"从Customer实体生成.如果我理解正确,我必须使用不同的插件(com.querydsl:querydsl-maven-plugin)来生成SCustomer查询类型?

    在查看querydsl-sql-example时,我没有看到任何实体类,所以我猜查询类型是由QueryDSL从数据库模式生成的?有没有办法从实体生成SCustomer查询类型,就像我们使用querydsl-jpa一样?

  3. 如果我们使用querydsl-sql,有没有办法在querydsl-sql查询中"重用"我们的querydsl-jpa谓词/ sorts/joins子句?或者我们是否必须使用特定于querydsl-sql的类复制该代码?

  4. 我也在考虑创建一个委托的数据库函数TIMESTAMPDIFF(SECOND, x, y),但它不是很便携......

  5. 我错过了什么吗?有没有更简单的方法来做我想做的事情?

jpql querydsl

6
推荐指数
1
解决办法
1137
查看次数

如何将本机数据库运算符 (postgres ~) 与 JPA 标准生成器一起使用?

我使用 JPA 2.0 标准构建以下查询(简化):

select n from notif n where n.message ~ 'b.*la'
Run Code Online (Sandbox Code Playgroud)

我正在使用 postgresql 数据库,我真的需要 ~ 运算符,而不是像。我可以使用与 CriteriaBuilder.function 等效的东西吗?或者,postgres 中是否有 ~ 运算符的函数形式,以便我可以使用提到的 cb.function 方法。我只找到了 postgresql regexp_matches 函数,但它返回一个匹配数组而不是布尔值。

解决方案:由于从标准 API 迁移到 JPQL 是不可能的,所以我最终编写了一个 postgres 函数:

'CREATE OR REPLACE FUNCTION "regexp_search"(character varying,character varying) RETURNS boolean AS \'select $1 ~ $2;\' LANGUAGE sql;'
Run Code Online (Sandbox Code Playgroud)

并用 cb.function 调用它:

Expression<Boolean> regexp_search = cb.function("regexp_search", Boolean.class, message,cb.literal(re));
Run Code Online (Sandbox Code Playgroud)

java postgresql jpa jpa-2.0

5
推荐指数
1
解决办法
4217
查看次数

标签 统计

java ×1

jpa ×1

jpa-2.0 ×1

jpql ×1

postgresql ×1

querydsl ×1