如何使用java streams对JPA repo中的字段进行分组和平均,并将其放入新集合中

如何使用java streams对JPA repo中的字段进行分组和平均,并将其放入新集合中,java,jpa,repository,grouping,java-stream,Java,Jpa,Repository,Grouping,Java Stream,我需要计算一周中选定的一天的平均入住率(例如,所有周五-每分钟)。由于缺少日期/时间函数,我没有找到解决此问题的任何JPQL/Querydsl解决方案。所以我尝试使用Java流。我的(简化)对象: 我的回购协议: @Query("select o from Occupancy o") public Stream<Occupancy> streamAllOccupancies(); 我还担心流的效率——它必须处理数据库中的所有记录。该流如何与jpa回购协议一起工作?首先SQL获取所有

我需要计算一周中选定的一天的平均入住率(例如,所有周五-每分钟)。由于缺少日期/时间函数,我没有找到解决此问题的任何JPQL/Querydsl解决方案。所以我尝试使用Java流。我的(简化)对象:

我的回购协议:

@Query("select o from Occupancy o")
public Stream<Occupancy> streamAllOccupancies();

我还担心流的效率——它必须处理数据库中的所有记录。该流如何与jpa回购协议一起工作?首先SQL获取所有记录,然后流处理它?或者它们是在每个记录上按顺序处理的?也许最好的解决方案是使用本机SQL查询而不是流?任何想法都会非常有用……

至于转换到
列表
,请注意
占用的
字段是
int
类型,而平均值可能是非整数。因此,我假设
占用率
类的定义如下:

class Occupancy {
   private LocalDateTime timeStamp;
   private double occupied;

   public Occupancy(LocalDateTime ts, double occ) {
       this.timeStamp = ts;
       this.occupied = occ;
   }
}
现在,您可以从生成的映射中再创建一个流:

List<Occupancy> occupancies = avgMap.entrySet().stream()
    .map(e -> new Occupancy(e.getKey(), e.getValue()))
    .collect(Collectors.toList());
有关详细信息,请参阅


还请注意,如果您的JDBC驱动程序实际上从服务器逐行获取数据(没有缓冲),这实际上可能会有更差的性能,因为您可能需要在DBMS和应用程序之间进行更多的往返(如果DBMS服务器位于不同的机器上,这可能特别重要)。因此,有关更多详细信息,请参阅JDBC驱动程序文档。

谢谢您的回答。当然,第二个流的解决方案是可行的,但我考虑只使用一个流和group->average,然后将结果放入列表中。我在开发中使用H2,但在prod中使用的是MySQL。谢谢你的提示。
new Occupancy( localTime, averagedOccupancy );
class Occupancy {
   private LocalDateTime timeStamp;
   private double occupied;

   public Occupancy(LocalDateTime ts, double occ) {
       this.timeStamp = ts;
       this.occupied = occ;
   }
}
List<Occupancy> occupancies = avgMap.entrySet().stream()
    .map(e -> new Occupancy(e.getKey(), e.getValue()))
    .collect(Collectors.toList());
@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE))