L’accesso ad un database relazionale da un’applicazione Java viene solitamente condotto con il protocollo JDBC – elastico ma dalla sintassi prolissa – o con framework dedicati come Hibernate o MyBatis la cui conoscenza richiede però una certa dose di studio. Proponiamo qui un’alternativa efficace ma dall’approccio immediato: Sql2o.
Vantaggi di Sql2o
Non ci vuole molto a notare i vantaggi di Sql2o anche perchè vengono ben pubblicizzati nell’homepage del progetto:
- la sintassi è ridotta all’osso: la stessa operazione svolta con JDBC classico può richiedere anche sette o otto volte le righe di codice di cui Sql2o necessita;
- i risultati di una query vengono mappati direttamente in classi Java: sarà sufficiente predisporre una sua definizione le cui proprietà abbiano nomi identici a ai campi dei record restituiti;
- anche nell’inserimento si potrà avere una mappatura inversa tra oggetti Java e record della tabella.
L’installazione è piuttosto comoda grazie alla disponibilità del progetto nei repository Maven, queste le coordinate da utilizzare:
<dependencies> <dependency> <groupId>org.sql2o</groupId> <artifactId>sql2o</artifactId> <version>1.5.4</version> </dependency> </dependencies>
In alternativa, si può scaricare il file in formato jar dal link fornito.
Nell’homepage viene dichiarata inoltre la compatibilità del progetto con la maggior parte dei DBMS più famosi come MySQL, PostgreSQL, Oracle e SQL Server ma in realtà lo si può utilizzare anche con altri, come il diffusissimo Sqlite, fornendo però il driver JDBC compatibile e caricandolo correttamente all’avvio dell’esecuzione.
Esempio
Vediamolo subito al lavoro.
Pensiamo ad una tabella che abbia la struttura fornita da tale definizione:
CREATE TABLE `persone` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `nome` TEXT, `cognome` TEXT, `eta` INTEGER, `citta` INTEGER );
e alla classe Java che rappresenterà i suoi record:
public class Persona { private long id; private String nome; private String cognome; private int eta; private String citta; /* * OMISSIS: tutti i getter e setter necessari * */ }
Con Sql2o possiamo eseguire una query utilizzando il seguente codice:
String sql = "SELECT * FROM persone"; try(Connection con = sql2o.open()) { List<Persona> persone = con.createQuery(sql) .executeAndFetch(Persona.class); }
Il codice usato è estremamente breve soprattutto in considerazione della quantità di lavoro che svolge. Infatti non solo saranno recuperati i record ma verranno tradotti ognuno in un oggetto Java e tutti insieme saranno restituiti come una lista di oggetti da utilizzare nel prosieguo delle operazioni.
Per le operazione di selezione dei record, si potrà evitare di concatenare stringhe alla query SQL mediante l’uso di parametri. Supponiamo di voler selezionare tutti record in cui il campo eta corrisponda almeno a quanto indicato nella variabile etaMinima e quello nel campo citta corrisponda a quanto riportato nella stringa cittaResidenza:
String selezione = "SELECT * FROM persone WHERE eta>=:sogliaEta AND citta=:citta"; try(Connection con = sql2o.open()) { List<Persona> persone = con.createQuery(selezione) .addParameter("sogliaEta", etaMinima) .addParameter("citta", cittaResidenza) .executeAndFetch(Persona.class);
L’utilizzo parametrico dei valori ricorda quello dei punti interrogativi nei PreparedStatement di JDBC ma la loro sostituzione con nomi simbolici preceduti dal simbolo due punti conferisce sicuramente più leggibilità al tutto.
Anche la sintassi dei comandi di modifica non si discosta molto da quanto abbiamo visto. Prendiamo, ad esempio, un’operazione di insert:
String sqlInsert = "INSERT INTO persone ( nome, cognome, eta, citta ) " + "values ( :nome, :cognome, :eta, :citta )"; try (Connection con = sql2o.open()) { int insertedId = (int) con.createQuery(sqlInsert, true) .addParameter("nome", "Saverio") .addParameter("cognome", "Rossi") .addParameter("eta", 48) .addParameter("citta", "Livorno") .executeUpdate() .getKey();
In questo caso, ci siamo fatti anche restituire l’id assegnato in autoincremento al nuovo record creato.
Inoltre per l’insert è disponibile anche il metodo bind che sarà in grado di mappare le proprietà di un oggetto Java con i campi del record da creare:
Persona nuovaPersona=new Persona(); /* * impsotazione delle proprietò nell'oggetto. * Sono i valori che andranno salvati nel nuovo record */ String sqlInsert = "INSERT INTO persone ( nome, cognome, eta, citta ) " + "values ( :nome, :cognome, :eta, :citta )"; try (Connection con = sql2o.open()) { con.createQuery(sql).bind(nuovaPersona).executeUpdate(); }
I parametri passati nel comando SQL corrispondono con le proprietà della classe Persona: si occuperà direttamente Sql2o di prelevarli dai vari membri dell’oggetto e di passarli nella direttiva insert.
Conclusioni
Da quanto abbiamo visto, Sql2o appare come un progetto utile in quanto produttivo ed essenziale. Ha diverse altre funzionalità che possono essere scoperte nella documentazione ufficiale. Noi, dopo questa introduzione, lo affronteremo ancora per vederlo al lavoro. Lo immaginate nella produzione di un servizio web con API REST in accoppiata con un altro prodotto snello come Spark Java?
Efficienza e sinteticità al vostro servizio!
No Responses to “Sql2o, accesso immediato ai database tramite Java”