2015-04-25 12 views
7

Używamy JPA2, Spring Data i QueryDSL w naszym projekcie. Mam następujące tabele i związane z nimi podmioty WZP:Wynik podobny do przestawnego z 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 dla Actitivy do ActivityName - działalność może mieć różne nazwy (np bieganie, jogging)

Osoba może mieć pewien poziom dla danej czynności i może wykonywać kilka czynności (każda z określonym poziomem).

  • Nie powinno być poszukiwanie z nazwami działalności (na przykład z systemem itp) jako parametrów (lista nazw aktywności)
  • W rezultacie wszystkie osoby powinny znajdować wykonujące pokrewne działalności.
  • Wynik powinien zawiera wszystkie działania szukać z ich odpowiednim poziomie, nazwisko osoby oraz ogólną sumę działań osób

przykład następujące dane:

  • Person = (id = 1 , nazwa = BOB)
  • osoby = (id = 2, nazwa = Maria)
  • Aktywność = (1, ...)
  • Aktywność = (2 ...)
  • ActivityName = (activity_id = 1, nazwa = "Jogging")
  • ActivityName = (activity_id = 1, nazwa = "uruchomiony")
  • ActivityName = (activity_id = 2, nazwa = "tańczyć")
  • activityLevel = (person_id = 1, activity_id = 1, poziom = 0.7f)
  • activityLevel = (person_id = 1, activity_id = 2, na poziomie = 0.1f)
  • activityLevel = (person_id = 2, activity_id = 1, poziom = 0,5f)

Wyszukiwanie osób "biegających" "Lub«taniec»powinien uzyskać wynik takiego:

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

Moje pytanie: Czy istnieje sposób JPA QL/QueryDSL aby uzyskać taki wynik z jeden ekspresji/projekcji? To, co już mam, to wielostopniowe rozwiązanie - wybór nazw i poziomów działania, wykonanie grupowania i sumowania za pomocą Java8. Jeśli zrobię zgrupowanie z querydsl, nie otrzymam wpisów pojedynczego poziomu. Na odwrót, w moim rozwiązaniu muszę wykonać kilka innych kroków.

Byłoby miło wiedzieć, czy jest to możliwe za pomocą zapytania.

Odpowiedz

2

Pure JPA & QueryDsl działa tylko z encjami. Można więc utworzyć widok bazy danych, który agreguje poszukiwane dane i zamapować je na nowy obiekt, który można po prostu wysłać do kwerendy.

Innym rozwiązaniem jest użycie natywnej obsługi zapytań jpa QueryDsl. Zobacz http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html dolna połowa. Będziesz potrzebował najniższego akapitu (zapytanie i projekt do DTO).

To sprowadza się do:

  • wygenerować klas Q, wskazując na db (schemat) (jestem pewien, dlaczego, co jest potrzebne, ale to w docs)
  • skonstruować kwerendę za pomocą com Klasa .mysema.query.jpa.sql.JPASQLQuery
  • Upewnij się, że wszystkie niezbędne pola listy wyników z zapytania w metodzie liście
  • Utwórz klasę dto fasoli, do którego można rzutować wynik
  • Project wynik do th e dto klasa
+0

Dzięki za odpowiedź. Jak powinna działać w tym przypadku dynamiczna baza danych? Przepraszam, nie znam tego. – swinkler

Powiązane problemy