我想显示一个二维图表,其中包含给定时间跨度内已处理对象的数量(在 JPA 中映射)。这个数量可以在 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('小时', t2 - t1) * 60 + date_part('分钟', t2 - t1)
。
为了在 JPQL 中使用这些数据库函数,您可以使用 FUNCTION
语法,例如 FUNCTION('date_part', 'day', :startDate - pageDate)
。
最后,您将按这样的表达式进行分组并按 id 进行计数,如下所示
选择计数(o.id)
来自 MyObject o
GROUP BY FUNCTION('date_part', 'day', :startDate - o.pageDate)
关于java - 将对象分类到桶中如何表述为有效的 JPQL 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34060883/