Ich muss die durchschnittliche Belegung für den ausgewählten Wochentag berechnen (zB alle Freitage - für jede Minute). Ich habe keine JPQL/Querydsl-Lösung für dieses Problem wegen fehlender Date/Time-Funktionen gefunden. Also versuche ich Java Streams zu benutzen. Mein (vereinfacht) Objekt:Wie man Felder aus dem JPA-Repo gruppiert und gemittelt und mit Java-Streams in eine neue Sammlung eingefügt wird
class Occupancy {
private LocalDateTime timeStamp;
private int occupied;
}
meine Repo:
@Query("select o from Occupancy o")
public Stream<Occupancy> streamAllOccupancies();
Beispiel:
try (Stream<Occupancy> stream = repository.streamAllOccupancies()) {
Function<Occupancy,LocalTime> OccupancyMinutesGrouping = (Occupancy o) -> {
return o.getDateTime().toLocalTime().truncatedTo(ChronoUnit.MINUTES);
};
Map<LocalTime,Double> avgMap = stream
.filter(o -> o.getDateTime().getDayOfWeek() == DayOfWeek.MONDAY) //example
.collect(
Collectors.groupingBy(
OccupancyMinutesGrouping,
Collectors.averagingInt(Occupancy::getOccupied)
)
);
}
Es funktioniert - aber ist es möglich, ändern Sie die Karte in die Liste meiner Belegungsobjekte:
new Occupancy(localTime, averagedOccupancy);
Ich bin auch Sorgen über die Effizienz der Streams - es muss alle Datensätze aus der Datenbank verarbeiten. Wie funktioniert der Stream mit jpa repo? Erste SQL bekommt alle Datensätze - dann Stream verarbeitet es? Oder werden sie nacheinander auf jedem Datensatz verarbeitet? Vielleicht ist die beste Lösung, eine Native SQL-Abfrage anstelle von Stream zu verwenden? Irgendwelche Ideen werden sehr hilfreich sein ...
Vielen Dank für Ihre Antwort. Natürlich funktioniert die Lösung mit dem zweiten Stream, allerdings habe ich überlegt, nur einen Stream und group-> average zu verwenden und dann die Ergebnisse in die Liste aufzunehmen. Ich benutze H2 in der Entwicklung - aber in prod. es wird MySQL sein. Danke für den Tipp. – Aragornx