
guide
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Utilizziamo il framework JOOQ tramite maven per la creazione di classi ORM
Dopo aver presentato in linea generale la libreria JOOQ nell’articolo precedente, ci dedicheremo stavolta a mostrare un esempio molto semplice di generazione automatica delle classi di mappatura ORM con maven.
Le classi per l’Object Relational Mapping risultano molto utili per semplificare la scrittura di codice pseudo-SQL, utilizzando le api di un linguaggio di programmazione ad oggetti come java
, o eventualmente una specifica DSL implementata tramite il linguaggio scala
, nel caso della libreria JOOQ.
Ci interessa a questo punto fare uso del mapping ad oggetti di JOOQ. A tal proposito nella libreria è presente una opportuna classe (org.jooq.util.DefaultGenerator
).
La classe può essere utilizzata da linea di comando in maniera del tutto simile alla seguente:
>> java -classpath lib/jooq-2.0.0.jar: lib/jooq-meta-2.0.0.jar: lib/jooq-codegen-2.0.0.jar: lib/mysql-connector-java-5.1.18.jar: . org.jooq.util.GenerationTool /hotel.properties
dove abbiamo cercato di formattare il comando per renderlo più leggibile: ovviamente andrà scritto invece su una sola riga, preoccupandoci di utilizzare i path corretti per le librerie relative (nel nostro esempio si fa riferimento ad una invocazione su console linux, dalla quale sia raggiungibile una directory “lib”) contenente le librerie.
L’elemento fondamentale di questa procedura assistita è il file di properties hotel.properties
, contenente le configurazioni minime perché possano essere prodotte le classi di mapping sul database dell’esempio introdotto nel precedente articolo:
jdbc.Driver=com.mysql.jdbc.Driver jdbc.URL=jdbc:mysql://localhost:3306/hotel jdbc.User=root jdbc.Password=root generator=org.jooq.util.DefaultGenerator generator.database=org.jooq.util.mysql.MySQLDatabase generator.database.input-schema=hotel generator.database.includes=.* generator.database.excludes= generator.generate.relations=true generator.target.package=it.html.articoli.esempi.jooq.generated generator.target.directory=src/main/java
Le classi prodotte avranno la struttura:
All’interno di questa struttura è infine abbastanza facile riconoscere la presenza di una classe per ogni tabella, e di una tabella “Tables
” che contiene un riferimento statico a ciascuna delle tabelle prodotte automaticamente (una sorta di bean
): questo ci permetterà -come vedremo tra poco- di semplificare la scrittura assistita di SQL per mezzo delle api appena prodotte tramite la code generation che abbiamo lanciato.
Una classe di particolare interesse è infine la HotelFactory
: in generale verrà creata una factory principale per ogni database di default, anche se è possibile modificare questo comportamento agendo sulla configurazione.
Per il nostro esempio abbiamo scelto di utilizzare maven
per gestire le dipendenze ed il build. Definiamo quindi un progetto principale Introduzione_JOOQ_parte_2
come parent pom e due moduli:
jooq-classi-generate
conterrà le classi prodotte dalla code generation di JOOQ
jooq-esempio-fluent-main
che conterrà l’esempio vero e proprio di utilizzo delle api
La parte che ci interessa maggiormente e che ci ha spinto a questa separazione è però la possibilità di generare le classi direttamente all’interno del ciclo di build di maven.
A tal proposito abbiamo scelto di utilizzare per semplicità la fase install
del modulo jooq-classi-generate
, separando il più possibile la scrittura assistita di codice dalla usuale compilazione e build/test
L’integrazione del plugin di JOOQ per maven richiede una configurazione simile alla seguente (per i dettagli si veda l’esempio allegato), che è corrispondente (ed alternativa, se si usa maven invece della riga di comando!) all’utilizzo del file properties già mostrato:
<build>
<plugins>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>...</dependencies>
<configuration>
<tasks>
<echo>GENERATING JAVA SOURCES with JOOQ...</echo>
</tasks>
<jdbc>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/hotel</url>
<user>root</user>
<password>root</password>
</jdbc>
<generator>
<name>org.jooq.util.DefaultGenerator</name>
<database>
<name>org.jooq.util.mysql.MySQLDatabase</name>
<includes>.*</includes>
<excludes></excludes>
<inputSchema>hotel</inputSchema>
</database>
<generate>
<relations>true</relations>
<deprecated>false</deprecated>
</generate>
<target>
<packageName>it.html.articoli.esempi.jooq.generated</packageName>
<directory>src/main/java</directory>
</target>
</generator>
</configuration>
</plugin>
</plugins>
</build>
Questo snippet farà parte nel nostro caso del file pom.xml del modulo di code generation
Partendo da questa idea iniziale è possibile personalizzare il proprio processo di build: in ogni caso per far girare l’esempio accontententiamoci di lanciare il comando >> mvn install
sul modulo jooq-classi-generate
per la generazione dei sorgenti prima del build complessivo vero e proprio sull’intero progetto.
Vogliamo a questo punto eseguire una query che ci consenta di stabilire i dettagli di prenotazione delle camere nel database del nostro albergo in un particolare giorno.
La query SQL che ci interessa riprodurre con JOOQ avrà una forma del tipo:
SELECT camere.numero, camere.piano, clienti.nominativo FROM camere JOIN prenotazioni ON (prenotazioni.camera = camere.numero) LEFT OUTER JOIN clienti ON (prenotazioni.idCliente = clienti.id) WHERE ( (prenotazioni.periodoAl <= '2006-07-15') AND (prenotazioni.periodoAl >= '2006-07-15') )
Come abbiamo già più volte anticipato JOOQ opera su connessioni già pronte ed aperte e non si preoccupa di chiuderle, quindi rimandiamo ai sorgenti in allegato per la parte di codice relativa. A partire dalla connessione attualmente aperta e se la precedente fase di generazione delle classi di “mappatura” è andata a buon fine, dovremmo essere in grado di scrivere qualcosa di simile:
HotelFactory jooq = new HotelFactory(connection);
con cui instanziamo la factory che ci aiuterà nella creazione delle query, esattamente come nell’esempio precedente, ma stavolta è facile osservare che si tratta di una factory specifica sul dominio del nostro database schema.
Giacchè i dati sono stati caricati nell’esempio precedente ci limitiamo ad azzerare le prenotazioni eventualmente presenti sul db per poter inserire dei dati ad hoc per il nostro esempio. Come si vedere svuotare una tabella è particolarmente semplice:
jooq.truncate(Tables.PRENOTAZIONI).execute();
jooq.truncate(CLIENTI).execute();
Da notare che mentre nel primo caso utilizziamo il nome completo della tabella Tables per accedere ad uno dei membri statici che al suo interno fanno riferimento alle classi generate da JOOQ per il mapping delle tabelle, nel secondo caso abbiamo utilizzato direttamente il riferimento “CLIENTI
” (riconoscibile perché convenzionalmente il nome è tutto in maiuscolo, come per le costanti)
É in genrale consigliabile per favorire la leggibilità importare staticamente questi riferimenti dalla classe Tables
, e anche qui rimandiamo ai sorgenti allegati.
import static it.html.articoli.esempi.jooq.generated.Tables.CLIENTI;
A questo punto inseriremo qualche dato di prova nel database, utilizzando due modalità differenti
Come prima cosa possiamo inserire dati e salvarli all’interno del db relazionandoci alle tabelle come se fossero oggetti, tramite le corrispettive classi generate:
ClientiRecord nuovoCliente = jooq.newRecord(CLIENTI);
nuovoCliente.setIndirizzo("nessun indirizzo");
nuovoCliente.setNominativo("nuovo cliente");
nuovoCliente.setTelefono("nessun telefono");
nuovoCliente.store();
naturalmente se volessimo cancellare i dati del cliente appena creato ci basterebbe scrivere
nuovoCliente.delete();
e anche le operazioni di update saranno molto simili. Ovviamente ClientiRecord
è un’altra delle classi create per noi da JOOQ, che in questo caso rappresenta un singolo record della tabella “clienti”
Una modalità ancora più interessante consente di inserire una serie di dati in modalità batch, e facendo uso finalmente delle api. É abbastanza semplice riconoscere le query SQL INSERT corrispondenti…
jooq.batch(
jooq.insertInto(CLIENTI, CLIENTI.NOMINATIVO, CLIENTI.INDIRIZZO)
.values("Luigi Bianchi","via vai, 13","06-1111"),
jooq.insertInto(PRENOTAZIONI, PRENOTAZIONI.IDCLIENTE, PRENOTAZIONI.CAMERA)
.values(1, 303),
//...
).execute();
Anche in questo caso abbiamo un po’ semplificato il codice mostrato per non appesantire la lettura e per sottolineare la semplicità d’uso delle api di JOOQ
É interessante notare come sia l’oggetto query
ad esporre un metodo execute
, in pieno stile ad oggetti.
Per stampare l’elenco delle prenotazioni possiamo allora scrivere:
// visualizziamo tutti i dati inseriti fin qui
Result<Record> result = jooq.select().from(CLIENTI).fetch();
System.out.println(result.format());
A questo punto non dovrebbe essere difficile leggere l’esempio seguente:
SelectConditionStep query = jooq.select(CAMERE.NUMERO, CAMERE.PIANO, CLIENTI.NOMINATIVO)
.from(CAMERE)
.join(PRENOTAZIONI).on(PRENOTAZIONI.CAMERA.equal(CAMERE.NUMERO))
.leftOuterJoin(CLIENTI).on(PRENOTAZIONI.IDCLIENTE.equal(CLIENTI.ID))
.where(PRENOTAZIONI.PERIODOAL.lessOrEqual("2006-07-15"))
.and(PRENOTAZIONI.PERIODOAL.greaterOrEqual("2006-07-15"));
query.execute();
result = query.fetch();
System.out.println("RISULTATO della QUERY (json):n"+result.formatJSON());
L’esempio mostra come costruiamo via via la query che avevamo immaginato tramite una composizione di chiamate a metodi sugli oggetti del nostro dominio, fino a farci stampare la tabella di dati corrispondenti. Anche qui abbiamo sfruttato una carattestica interessante che certo piacerà molto a chi si occupa di produrre semplici report: ogni risultato espone dei metodi di trasformazione in html, xml, csv e json (che è la soluzione mostrata), oltre che la semplice stampa testuale mostrata precedentemente.
A questo punto risulta chiaro che questa libreria offre moltissime funzionalità in maniera molto semplice, ed essendo tutt’ora in fase di evoluzione può costituire uno strumento via via interessante da integrare nei nostri progetti java. Ancora più interessante e semplice da usare è l’utilizzo via DSl con scala, che qui abbiamo dovuto omettere perché esulava dai nostri scopi
In ogni caso per gli opportuni approfondimenti è bene seguire il manuale ufficiale di JOOQ, che è ricco di contenuti semplici e molto chiari
L’esempio che abbiamo scelto di mostrare è particolarmente semplice e serve soltanto a dare una idea generale delle potenzialità di una libreria tutt’ora in fase di evoluzione, e che andrebbe considerata se si desidera utilizzare un approccio “ad oggetti” per le interrogazioni SQL, senza avere necessariamente bisogno delle complessità di ORM completi, quali hibernate o ibatis, ad esempio.
Se vuoi aggiornamenti su JOOQ: generazione ORM via maven inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
In questo breve video vedremo come sia facile installare i programmi che ci servono sulla nostra installazione di Ubuntu. Basterà […]
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Come creare applicazioni per il Web con PHP e MySQL per il DBMS.
Tutte le principali tecnologie per diventare uno sviluppatore mobile per iOS.
I fondamentali per lo sviluppo di applicazioni multi piattaforma con Java.
Diventare degli esperti in tema di sicurezza delle applicazioni Java.
Usare Raspberry Pi e Arduino per avvicinarsi al mondo dei Maker e dell’IoT.
Le principali guide di HTML.it per diventare un esperto dei database NoSQL.
Ecco come i professionisti creano applicazioni per il Cloud con PHP.
Lo sviluppo professionale di applicazioni in PHP alla portata di tutti.
Come sviluppare applicazioni Web dinamiche con PHP e JavaScript.
Fare gli e-commerce developer con Magento, Prestashop e WooCommerce.
Realizzare applicazioni per il Web utilizzando i framework PHP.
Creare applicazioni PHP e gestire l’ambiente di sviluppo come un pro.
Percorso base per avvicinarsi al web design con un occhio al mobile.
Realizzare siti Web e Web application con WordPress a livello professionale.
Come creare database e collection, inserire, estrarre, aggiornare e rimuovere dati da una base di dati MongoDB con Python
Impariamo ad utilizzare Takamaka, una blockchain Java Full Stack, per scrivere codice Java installabile ed eseguibile su una blockchain
Realizziamo concretamente il layout di un’interfaccia grafica. Esempi e suggerimenti
Guida a Red Hat Quarkus, uno stack Java Kubernetes nativo pensato per applicazioni serverless e per la realizzazione di microservizi rapidi ed ottimizzati. Una piattaforma concepita per accedere in ambiente Cloud mettendo a disposizione un framework orientato ai microservizi, come ad esempio Spring Boot o Micronaut