如何使用java streams对JPA repo中的字段进行分组和平均,并将其放入新集合中
我需要计算一周中选定的一天的平均入住率(例如,所有周五-每分钟)。由于缺少日期/时间函数,我没有找到解决此问题的任何JPQL/Querydsl解决方案。所以我尝试使用Java流。我的(简化)对象: 我的回购协议:如何使用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获取所有
@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))