我想在给定的时间跨度内显示包含已处理对象数量(以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)