Tag: SqlResultSetMapping
La bellezza si trova negli occhi di chi guarda. Così fa la “facilità”:
ulteriori informazioni su SQL Set di Risultati Mapping e gestire la vostra nativo risultati della query con facilità: http://t.co/WH4BTlClIP #APP #Java #JavaEE
— Thorben Janssen (@thjanssen123) aprile 15, 2015
Thorben scrive molto bene e articoli utili su JPA, e recentemente ha iniziato una proficua serie JPA 2.1 nuove caratteristiche. Tra cui: Mappatura dei set di risultati. Potresti conoscere la mappatura dei set di risultati da siti Web come CTMMC, o annotatiomania.com. Possiamo riassumere questa procedura di mappatura come segue:
a) definire la mappatura
@SqlResultSetMapping( name = "BookAuthorMapping", entities = { @EntityResult( entityClass = Book.class, fields = { @FieldResult(name = "id", column = "id"), @FieldResult(name = "title", column = "title"), @FieldResult(name = "author", column = "author_id"), @FieldResult(name = "version", column = "version")}), @EntityResult( entityClass = Author.class, fields = { @FieldResult(name = "id", column = "authorId"), @FieldResult(name = "firstName", column = "firstName"), @FieldResult(name = "lastName", column = "lastName"), @FieldResult(name = "version", column = "authorVersion")})})
La mappatura sopra è piuttosto semplice. Specifica come le colonne del database devono essere mappate ai campi entità e alle entità nel loro complesso. Quindi si assegna a questa mappatura un nome ("BookAuthorMapping"
), che è quindi possibile riutilizzare in tutta l’applicazione, ad esempio con query JPA native.
Mi piace in particolare il fatto che Thorben scriva quindi:
Se non ti piace aggiungere un enorme blocco di annotazioni alla tua entità, puoi anche definire la mappatura in un file XML
… Quindi, siamo tornati a sostituire enormi blocchi di annotazioni con enormi blocchi di XML – una tecnica che molti di noi volevano evitare di usare le annotazioni… :- )
b) applicare la mappatura
Una volta che la mappatura è stata definita staticamente su alcuni tipi Java, è possibile recuperare tali entità applicando quanto sopra BookAuthorMapping
List<Object> results = this.em.createNativeQuery( "SELECT b.id, b.title, b.author_id, b.version, " + " a.id as authorId, a.firstName, a.lastName, " + " a.version as authorVersion " + "FROM Book b " + "JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();results.stream().forEach((record) -> { Book book = (Book)record; Author author = (Author)record;});
Nota come devi ancora ricordare i tipi Book
e Author
e lanciare esplicitamente poiché nessuna informazione di tipo verificabile è davvero collegata a nulla.
La definizione di “complesso”
Ora, l’articolo afferma che questa è una mappatura “complessa”, e senza dubbio, sarei d’accordo. Questa query molto semplice con solo un semplice join innesca già un tale disordine di annotazione se vuoi mappare davvero le tue entità tramite JPA. Non vuoi vedere le annotazioni di mappatura di Thorben, una volta che le query diventano un po ‘ più complesse. E ricorda, @SqlResultSetMapping
riguarda la mappatura (nativa!) Risultati SQL, quindi non siamo più in object-graph-persistence land, siamo in SQL land, dove il recupero di massa, la denormalizzazione, l’aggregazione e altre cose SQL “fantasiose” è il re.
Il problema è qui:
Java 5 ha introdotto annotazioni. Le annotazioni erano originariamente destinate ad essere utilizzate come “modificatori artificiali”, cioè cose come static
, final
, protected
(è interessante notare che Ceylon conosce solo annotazioni, nessun modificatore). Questo ha senso. I progettisti di linguaggi Java potrebbero introdurre nuovi modificatori / “parole chiave” senza rompere il codice esistente, perché le parole chiave “reali” sono parole riservate, che sono difficili da introdurre in una lingua. Ricorda enum
?
Quindi, i buoni casi d’uso per le annotazioni (e ce ne sono solo pochi) sono:
@Override
-
@Deprecated
(anche se, un attributo di commento sarebbe stato di fantasia) @FunctionalInterface
JPA (e altre API Java EE, così come Spring) sono andati completamente fuori di testa sul loro uso di annotazioni. Ripeti dopo di me:
Nessuna lingua
@Before
o@After
Java ha mai abusato di annotazioni tanto quanto Java(l’idea @ Before / @ After era di lennoff, su reddit)
C’è un forte déjà vu in me quando leggo quanto sopra. Ti ricordi quanto segue?
Nessuna lingua prima o dopo Java ha mai abusato delle eccezioni controllate tanto quanto Java
Tutti rimpiangeremo profondamente le annotazioni Java entro il 2020.
Le annotazioni sono una grande verruca nel sistema di tipo Java. Hanno un uso giustificato estremamente limitato e ciò che gli sviluppatori Java Enterprise stanno facendo in questi giorni non è assolutamente entro i limiti di “giustificato”. Li stiamo abusando per la configurazione di cose per cui dovremmo davvero scrivere codice.
Ecco come eseguire la stessa query con jOOQ (o qualsiasi altra API che sfrutta i generici e la sicurezza del tipo per SQL):
Book b = BOOK.as("b");Author a = AUTHOR.as("a");DSL.using(configuration) .select(b.ID, b.TITLE, b.AUTHOR_ID, b.VERSION, a.ID, a.FIRST_NAME, a.LAST_NAME, a.VERSION) .from(b) .join(a).on(b.AUTHOR_ID.eq(a.ID)) .fetch() .forEach(record -> { BookRecord book = record.into(b); AuthorRecord author = record.into(a); });
Questo esempio combina sia le annotazioni di JPA 2.1 CHE le query. Tutte le meta informazioni sulle “entità” proiettate sono già contenute nella query e quindi nel Result
prodotto dal metodo fetch()
. Ma non importa, il punto qui è che questa espressione lambda…
record -> { BookRecord book = record.into(b); AuthorRecord author = record.into(a);}
… può essere tutto quello che vuoi! Come gli esempi più sofisticati che abbiamo mostrato nei post del blog precedenti:
- Non c’è più bisogno di ORM
- Trasforma i tuoi dati SQL in grafici Usando jOOQ e JavaFX
La mappatura può essere definita ad hoc, al volo, usando le funzioni. Le funzioni sono i mappatori ideali, perché prendono un input, producono un output e sono completamente apolidi. E la cosa migliore delle funzioni in Java 8 è che sono compilate dal compilatore Java e possono essere utilizzate per digitare-controllare la mappatura. Ed è possibile assegnare funzioni agli oggetti, che consente di riutilizzare le funzioni, quando un determinato algoritmo di mappatura può essere utilizzato più volte.
Infatti, la clausola SQL SELECT
stessa è una tale funzione. Una funzione che trasforma tuple / righe di input in tuple / righe di output e puoi adattare quella funzione al volo usando espressioni aggiuntive.
Non c’è assolutamente modo di digitare-controllare nulla nella precedente istruzione SQL nativa JPA 2.1 e nell’esempio @SqlResultSetMapping
. Immagina di cambiare il nome di una colonna:
List<Object> results = this.em.createNativeQuery( "SELECT b.id, b.title as book_title, " + " b.author_id, b.version, " + " a.id as authorId, a.firstName, a.lastName, " + " a.version as authorVersion " + "FROM Book b " + "JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();
Hai notato la differenza? La colonna b.title
è stata rinominata in book_title
. In una stringa SQL. Che esplode in fase di esecuzione! Come ricordare che devi anche adattarti
@FieldResult(name = "title", column = "title")
… per essere
@FieldResult(name = "title", column = "book_title")
Al contrario, come ricordare che una volta rinominato column
nel tuo @FieldResult
, dovrai anche andare a controllare ovunque venga utilizzato questo "BookAuthorMapping"
e anche cambiare i nomi delle colonne in quelle query.
@SqlResultSetMapping( name = "BookAuthorMapping", ...)
Le annotazioni sono cattive
Puoi o non puoi essere d’accordo con alcune delle precedenti. Si può o non può piacere jOOQ come alternativa a JPA, che è perfettamente bene. Ma è davvero difficile non essere d’accordo con il fatto che:
- Java 5 introdotto molto utili annotazioni
- Java EE / Primavera pesantemente abusato di quelle annotazioni per sostituire XML
- ora Abbiamo un universo parallelo sistema di tipi in Java
- Questo universo parallelo tipo di sistema è completamente inutile, perché il compilatore non è in grado analizzare it
- Java SE 8 introduce la programmazione funzionale e un sacco di inferenza del tipo
- Java SE 9-10 introdurrà più impressionante caratteristiche del linguaggio
- ora diventa chiaro che ciò che era di configurazione XML (o annotazioni) dovrebbe essere stato del codice, in primo luogo,
- JPA 2.1 è diventato il nuovo EJB 2.0: Obsoleto
Come ho detto. Difficile non essere d’accordo. O in altre parole:
Il codice è molto meglio nell’esprimere algoritmi rispetto alla configurazione
Ho incontrato Thorben personalmente in diverse occasioni a conferenze. Questo sproloquio qui non è stato pensato personalmente, Thorben 🙂 I tuoi articoli su JPA sono molto interessanti. Se i lettori di questo articolo utilizzano JPA, si prega di consultare il blog di Thorben: http://www.thoughts-on-java.org.
Nel frattempo, mi piacerebbe nominare Thorben per il titolo rispettato “The Annotatiomaniac of the Year 2015”
Scrivi una risposta o commento.