2015-04-25 7 views
7

Wir verwenden JPA2, Spring Data und QueryDSL in unserem Projekt. Ich habe die folgenden Tabellen und zugehörige JPA-Entitäten:Pivot-like Ergebnis mit JPA/QueryDSL

table Person (id, ...) 

table Activity (id, type, ...) 

@Entity 
@Configurable 
public class Activity { 
    @ElementCollection 
    @CollectionTable(joinColumns = @JoinColumn(name = "ACTIVITY_ID")) 
    @NotEmpty 
    @Valid 
    private Set<ActivityName> names = new HashSet<>(); 

table ActivityName(activity_id, name, ...) 

@Embeddable 
    @Immutable 
    @Table(uniqueConstraints = @UniqueConstraint(columnNames = "NAME")) 
    public static class ActivityName { ... } 

table ActivityLevel(person_id, activity_id, level) 

@Entity 
@Immutable 
@Validated 
public final class ActivityLevel{...} 

1..n für Actitivy zu Activity - eine Aktivität, unterschiedliche Namen haben könnte (zB Laufen, Joggen)

Eine Person könnte ein gewisses Niveau hat für eine bestimmte Aktivität und kann mehrere Aktivitäten (jeweils mit einem definierten Level) durchführen.

  • Es soll eine Suche mit Aktivität Namen (z Laufen etc.) als Parameter (eine Liste der Aktivitätsnamen)
  • Als Ergebnis all Personen gefunden werden sollen, die die entsprechende Tätigkeit ausüben.
  • Das Ergebnis alle Aktivitäten für ihre entsprechenden Ebene gesucht werden soll enthält, den Namen der Person und die gesamte Summe der Aktivitäten Personen

Beispiel die folgenden Daten:

  • Person = (id = 1 Bob, name =)
  • Person = (id = 2, name = Mary)
  • Aktivität = (1, ...)
  • Aktivität = (2, ...)
  • Activity = (activity_id = 1, name = "Tippen")
  • Activity = (activity_id = 1, name = "running")
  • Activity = (activity_id = 2, name = "Tanzen")
  • activity = (person_id = 1, activity_id = 1, level = 0.7f)
  • activity = (person_id = 1, activity_id = 2, level = 0.1F)
  • activity = (person_id = 2, activity_id = 1, Stufe = 0.5f)

Suche nach Personen, die "rennen" "Oder‚Tanz‘sollte ein Ergebnis wie folgt erhalten:

Person[Name] ActitiyName ActivityLevel ActitiyName ActivityLevel Sum 
Bob    running   0.7   dancing   0.1  0.8 
Mary   running   0.5         0.5   

Meine Frage: Gibt es eine JPA QL/QueryDSL Weg, ein solches Ergebnis zu erhalten mit ein Ausdruck/Projektion? Was ich bereits habe, ist eine mehrstufige Lösung - Auswahl von Aktivitätsnamen und Ebenen, Durchführung der Gruppierung und Summe mit Java8. Wenn ich die Gruppierung mit querydsl mache, bekomme ich die Einstufen-Einträge nicht. Umgekehrt muss ich in meiner Lösung noch einige andere Schritte durchführen.

Wäre schön zu wissen, ob dies nur durch eine Abfrage möglich ist.

Antwort

2

Reine JPA & QueryDsl funktioniert nur mit Entitäten. Sie könnten also eine db-Ansicht erstellen, die die gesuchten Daten aggregiert und sie einer neuen Entität zuordnet, die Sie einfach abfragen können.

Eine weitere Lösung ist die native jpa-Abfrageunterstützung von QueryDsl. Siehe http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html untere Hälfte. Sie benötigen den niedrigsten Absatz (Abfrage und Projekt in DTO).

Es läuft darauf hinaus:

  • generieren Q Klassen von dem db zeigt (Schema) (ich bin nicht sicher, warum das nötig ist, aber es ist in der Dokumentation)
  • eine Abfrage, die com mit .mysema.query.jpa.sql.JPASQLQuery Klasse
  • Stellen Sie sicher, alle notwendigen Ergebnisfeld in der Liste Methode aus der Abfrage zur Liste
  • eine dto Bean-Klasse erstellen, auf die Sie das Ergebnis projizieren kann
  • Projekt das Ergebnis Zahn e dto Klasse
+0

Danke für Ihre Antwort. Wie sollte eine dynamische DB in diesem Fall funktionieren? Entschuldigung, mir ist das nicht bekannt. – swinkler