2015-04-25 9 views
7

Nel nostro progetto utilizziamo JPA2, Spring Data e QueryDSL. Ho le seguenti tabelle e le relative entità JPA:Risultato simile a un pivot con 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 per Actitivy a activityName - un'attività potrebbe avere nomi diversi (ad esempio corsa, jogging)

Una persona potrebbe avere un certo livello per una determinata attività e può compiere diverse attività (ciascuna con un livello definito).

  • Ci dovrebbe essere una ricerca con i nomi di attività (per esempio in esecuzione, ecc) come parametri (un elenco di nomi di attività)
  • Di conseguenza tutte le persone dovrebbero trovare che svolgono l'attività correlata.
  • Il risultato dovrebbe contiene Visualizza tutte le attività con il loro livello corrispondente, il nome della persona e la somma complessiva delle attività di persone

Esempio i seguenti dati:

  • persona = (id = 1 , name = Bob)
  • persona = (id = 2, name = Mary)
  • attività = (1, ...)
  • attività = (2, ...)
  • 01.235.
  • activityName = (activity_id = 1, name = "fare jogging")
  • activityName = (activity_id = 1, name = "running")
  • activityName = (activity_id = 2, name = "ballare")
  • activityLevel = (person_id = 1, activity_id = 1, livello = 0.7f)
  • activityLevel = (person_id = 1, activity_id = 2, livello = 0.1f)
  • activityLevel = (person_id = 2, activity_id = 1, livello = 0.5f)

Ricerca di persone "in esecuzione" "O "ballare" dovrebbe ottenere un risultato simile a questo:

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

La mia domanda: C'è un modo JPA QL/QueryDSL per ottenere un risultato del genere con uno espressione/proiezione? Quello che ho già è una soluzione multi-passo - selezionando nomi e livelli di attività, eseguendo il raggruppamento e sommando con Java8. Se faccio il raggruppamento con querydsl, non ottengo le voci a livello singolo. Viceversa, nella mia soluzione devo eseguire diversi altri passaggi.

Sarebbe bello sapere se questo è possibile solo utilizzando una query.

risposta

2

Pure JPA & QueryDsl funziona solo con le entità. Così puoi creare una vista db che aggrega i dati che stai cercando e associalo a una nuova entità, che puoi semplicemente interrogare.

Un'altra soluzione è l'utilizzo del supporto di query jpa nativo di QueryDsl. Vedi http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html metà inferiore. Avresti bisogno del paragrafo più basso (Query e progetto in DTO).

Si riduce a:

  • generare classi Q puntando al db (schema) (io sono sicuri perché ciò che è necessario, ma è nella documentazione)
  • creare una query utilizzando il com classe .mysema.query.jpa.sql.JPASQLQuery
  • Assicurati di elencare tutti i campi risultato necessario dalla query nel metodo lista
  • Creare una classe dto chicco alla quale è possibile proiettare il risultato
  • progetto il risultato a th e dto class
+0

Grazie per la risposta. Come dovrebbe funzionare un DB dinamico in questo caso? Scusa, non ho familiarità con questo. – swinkler

Problemi correlati