java – 如何将对象排序到桶中,将其表示为有效的JPQL表达式?

我想在给定的时间跨度内显示包含已处理对象数量(以JPA映射)的2D图表.在30分钟的时间内,此数量可以扩展到大约30k个对象.

作为DBMS,我在版本4.2.21中使用PostgreSQL 9.4和JPA 2.0与Hibernate.

目前我正在使用这段代码,以便将金额添加到我的时间“桶”中.

 // Get all objects after a given start date
List<MyObject> myObjects= myJPADbService.getMyObjects(Date.from(startDate.atZone
            (ZoneId.systemDefault()).toInstant()), Integer.MAX_VALUE);

for (MyObject information : myObjects) {
        LocalDateTime pageDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(information.getLastSeen().getTime()), ZoneId.systemDefault());          
    long duration;
    if (temporalUnit == ChronoUnit.MINUTES) {
     duration = Duration.between(startDate, pageDate).toMinutes();
    } else if (temporalUnit == ChronoUnit.DAYS) {
     duration = Duration.between(startDate, pageDate).toDays();
    } else {
     duration = Duration.between(startDate, pageDate).toHours();
   }

  pagesPerUnit[(int) (Math.abs(duration))]++;
}

但是,根据用户选择的时间跨度,这段代码可能效率很低.如果DBMS根据用户选择的时间跨度计算存储桶,则可能更有效.

如何用适当的JPQL语法来表达它?

最佳答案 首先,您需要一种JPA方法来计算相应单元中startDate和pageDate之间的差异,这有点难以制定,因为它非常依赖于数据库.最后,您将需要一些自定义函数或编写非常复杂的JPQL查询.

计算PostgreSQL中两个日期之间的天数就像做date_part(‘day’,t2-t1)一样简单.对于你已经需要的时间date_part(‘day’,t2-t1)* 24 date_part(‘hour’,t2-t1)和分钟date_part(‘day’,t2-t1)* 24 * 60 date_part(‘hour’, t2 – t1)* 60 date_part(‘分钟’,t2 – t1).

为了在JPQL中使用这些数据库函数,您可以使用FUNCTION(‘date_part’,’day’,:startDate – pageDate)等FUNCTION语法.

最后,您将通过这样的表达式进行分组并按ID进行计数,如下所示

SELECT COUNT(o.id)
来自MyObject o
GROUP BY FUNCTION(‘date_part’,’day’,:startDate – o.pageDate)

点赞