JDBC
JDBC (Java Database Connectivity) èun'interfaccia completamente Java utilizzata per eseguireistruzioni SQL (Structured Query Language, cheè il linguaggio standard per l'interrogazione,l'inserimento, la modifica e la cancellazione dei datidei database), ossia fornisce una libreria standard perl'accesso a database SQL. Ciononostante, sebbenestandardizzi il meccanismo di connessione ai database, lasintassi per inviare richieste ed effettuare transazioni e lastruttura dei dati che rappresentano i risultati, JDBC nonstandardizza la sintassi SQL.
Le 4 operazioni indicate sopra, ossia l'interrogazione,l'inserimento, la modifica e la cancellazione dei datidei database possono essere eseguite facilmente attraverso leseguenti 4 istruzioni SQL.
Effettuare ricerche: l'istruzione SELECT
SELECT dato1, dato2 FROM tabella1
seleziona tutti i valori contenuti nei campi dato1 e dato2della tabella tabella1. È possibile selezionare tuttii campi mettendo un * al posto dei singoli nomi dei campi.
SELECT * FROM tabella1 WHERE dato1=5
impone una condizione alla ricerca infatti seleziona solo irecord per i quali è valida la condizione dato1=5.
SELECT * FROM tabella1 ORDER BY dato1
la clausola ORDER BY viene utilizzata per ordinare i valoricontenuti in uno o più campi. Di defaultl'ordinamento è crescente ma è possibilespecificare l'inverso scrivendo DESC dopo i nomi deicampi su cui effettuare l'ordinamento.Con una serie difunzioni è possibile contare, calcolare il totale, lamedia, il minimo e il massimo da un insieme di dati.
SELECT SUM(dato1) FROM tabella1
Restituisce la somma di tutti i valori del campo dato1, acondizione che l'operazione sia possibile sul tipo didato
SELECT AVG(dato1) FROM tabella1
Restituisce la media i valori del campo dato1, a condizioneche l'operazione sia possibile sul tipo di dato
SELECT MAX(dato1) FROM tabella1
Restituisce il massimo dei valori del campo dato1 acondizione che sul dato sia possibile eseguirel'operazione di ordinamento.
SELECT MIN(dato1) FROM tabella1
Restituisce il minimo dei valori del campo dato1 a condizioneche sul dato sia possibile eseguire l'operazione diordinamento.
SELECT COUNT(*) FROM tabella1 WHERE data1=5
Questa operazione restituisce il numero di record chesoddisfano la condizione imposta. Ovviamente le funzioniviste possono essere combinate tra loro come
SELECT MAX(dato1), MIN(dato1), AVG(dato1) FROM tabella1
che restituisce il massimo, il minimo e la media di dato1
Effettuare cancellazioni: l'istruzione DELETE
DELETE FROM tabella1 WHERE dato1=5
In questo modo vengono cancellati tutti i record dellatabella tabella1 nei quali è vera la condizione chedato1=5. Se non si utilizza la clausola WHERE vengonocancellati tutti i record della tabella.
Effettuare inserimenti: l'istruzione INSERT
INSERT INTO tabella1 (dato1, dato2, dato3) VALUES (valore1, valore2, valore3)
Inserisce nella tabella tabella1, nei campi dato1, dato2,dato3 i valori specificati all'interno della parentesidopo la parola chiave VALUES.
Effettuare aggiornamenti: l'istruzione UPDATE
UDPATE tabella1 SET dato1 = nuovo_valore WHERE dato1=5
Pone uguali al nuovo valore il campo dato1 di tutti i recorddi tabella1 che soddisfano la condizione stabilita. Se nonviene specificata nessuna condizione l'aggiornamentoviene eseguito su tutti i record della tabella.
Passiamo ora da questa breve appendice sul linguaggio SQLall' argomento principale del capitolo, che èJDBC: l'implementazione più utilizzata di questainterfaccia è quella detta con bridge JDBC - ODBC. Inquesto caso il driver JDBC funge da ponte per accedere aldatabase attraverso driver ODBC, che deve essere presente econfigurato sul server. Esistono però altreimplementazioni che differiscono per il modo di operare dellestesse:
Driver API - nativa Questa tecnica si interfacciadirettamente con i database commerciali, convertendo icomandi JDBC in chiamate specifiche del DBMS (Data BaseManage System), il sistema di gestione di basi di dati.E'possibile perciò accedere a database SQL divario tipo usando la stessa sintassi Java.
Driver puro Java
È un driver puro Java che comunica direttamente con ildatabase, convertendo i comandi JDBC nel protocollo delmotore di database. Questa è senza dubbio la soluzionemigliore perché non richiede nessuna traduzioneaggiuntiva.
In seguito, e in particolare nelle applicazioni pratiche(vedi capitolo relativo), si prenderà inconsiderazione il driver del primo tipo (bridge JDBC - ODBC)perché, come già detto, è il piùdiffuso e utilizzato anche nelle applicazione puramente Javaed è il più semplice. Ci sono 7 passifondamentali da seguire nell'interrogazione di undatabase:
Caricare il driver JDBC;
Definire l'URL di connessione;
Stabilire la connessione;
Creare un oggetto statement;
Eseguire una richiesta o un aggiornamento;
Processare il risultato;
Chiudere la connessione.
Il driver è quel pezzo di software che conosce il mododi parlare al database server, per4 caricarlo èsufficiente caricare la classe appropriata. Ecco un esempio:
try { Class.forName("connect.microsoft.MicrosoftDriver"); Class.forName("oracle.jdbc.driver.OracleDriver"); Class.forName("com.sybase.jdbc.SybDriver"); } catch(ClassNotFoundException cnfe) { System.err.println("Error loading driver: " + cnfe); }
Il metodo Class.forName prende una striga che rappresenti ilnome di una classe e carica la classe corrispondente. Questaoperazione può dare origine, come nell'esempio, adelle ClassNotFoundException. Una volta caricato il driver,è necessario specificare l'URL del databaseserver, Gli URL che si riferiscono a database usano ilprotocollo jdbc: e contengono il server host, la porta e ilnome del database. Eccone un esempio:
String host = "dbhost.yourcompany.com"; String dbName = "someName"; int port = 1234; String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + dbName; String sybaseURL = "jdbc:sybase:Tds:" + host + ":" + port + ":" + "?SERVICENAME=" + dbName;
Pere rendere attiva una connessione, è necessariopassare l'URL, lo username del database e la password peril metodo getConnection della classe DriverManager, comenell'esempio:
String username = "jay_debesee"; String password = "secret"; Connection connection = DriverManager.getConnection(oracleURL, username, password);
E'anche possibile ottenere informazioni relative aldatabase usando il metodo getMetaData di Connection. Questometodo restituisce un oggetto DatabaseMetaData che ha imetodo per ricavare il nome del database e la sua versione(getDatabaseName, getDatabaseProductVersion) o del driverJDBC (getDriverName, getDriverVersion). Ad esempio:
DatabaseMetaData dbMetaData = connection.getMetaData(); String productName = dbMetaData.getDatabaseProductName(); System.out.println("Database: " + productName); String productVersion = dbMetaData.getDatabaseProductVersion(); System.out.println("Version: " + productVersion);
Un oggetto di statement è usato per inviare richiestee comandi al database ed è creato dalla Connection nelmodo che segue:
Statement statement = connection.createStatement();
Una volta che si ha un oggetto Statement è possibileutilizzare per inviare una richiesta SQL usando il metodoexecuteQuery, che restituisce un oggetto di tipo ResultSet.Ecco un esempio:
String query = "SELECT col1, col2, col3 FROM sometable"; ResultSet resultSet = statement.executeQuery(query);
Se si desidera modificare il database, si useràanziché la executeQuery la executeUpdate includendouna stringa del tipo UPDATE,INSERT o DELETE. Il modopiù semplice per processare un risultato èfarlo una colonna per volta usando il metodo ResultSet.nextper spostarsi all'interno di una tabella una colonna pervolta:
while(resultSet.next()) { System.out.println(results.getString(1) + " " + results.getString(2) + " " + results.getString(3)); }
Come si vede in questo caso specifico, ResultSet prevede varimetodi di get che prendono un indice o un nome di colonnacome argomento e restituisce risultati che possono essere divari tipi Java. I metodi di lettura dei campidell'oggetto ResultSet si differenziano in base al tipocampo. Ecco un breve tabella che elenca i tipi di variabiledel database e i rispettivi metodi da utilizzare.
Metodo | Tipo del campo |
getInt() | Numerico intero |
getFloat() | Numerico con virgola |
getByte() | Numerico byte |
getlong() | Numerico lungo |
getString() | Stringa |
getBoolean() | Booleano (si/no) |
getDate() | Data |
Per muovere in avanti il cursore ResultSet si utilizza la ilmetodo next() dell'oggetto stesso, che restituisce unvalore booleano che indica se il cursore è arrivato altermine dalla tabella. È sufficiente creare un ciclowhile(rs.next()) per scorrere senza ulteriori istruzioni irecords della base di dati. Se è necessarioaggiornare, inserire, modificare o eliminare records di unbatabase, il codice varia leggermente, infatti l'oggettoResultSet non è più necessario visto chel'operazione non restituisce più un riferimento aduna tabella creata con un'istruzione select. Èsufficiente richiamare il metodo executeUpdate()dell'oggetto Statement precedentemente definito, e darecome ingresso la query SQL (Insert, update, create table).Questo metodo restituisce un valore intero che èuguale a 1 se tutto è stato eseguito con successo.È bene quindi effettuare un controllo sul valorerestituito in modo da riuscire a capire se la modifica aldatabase sia effettivamente riuscita e comportarci diconseguenza. Vediamo un esempio:
<html><head><title>Esempio inserimento riga nel DataBase</title></head><body><%- deve essere importata il package java.sql.* per eseguirele istruzioni SQL -%><%@ page language="java" import="java.sql.*" %><%int valore = 25; //valore di esempioint esito; //esito aggiornamentoConnection conn = null;//carica il file di classe del driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//crea la connessione con l'origine dati conn = DriverManager.getConnection("jdbc:odbc:miodb" ,"" ,"");//crea lo statement Statement st = conn.createStatement();//esegue l'aggiornameto o l'inserimento esito = st.executeUpdate("INSERT INTO tab1 (dati) values (" +valore+ ")")) //se esito è uguale a 1 tutto è andato bene if (esito == 1) out.println("inserimento eseguito correttamente"); else out.println("inserimento non eseguito");rs.close(); conn.close(); %> </body> </html>
Nell'esempio è stato inserito nella tabella"tab1" , nel campo "dati" , il valoredella variabile "valore" , che era stata definita einizializzata precedentemente, ma che in praticaproverrà quasi sempre da un inserimento di dati.Ciò è stato possibile con una sempliceoperazione di concatenazione di stringhe (per farlo si usa +)per creare la query SQL che si occupa dell'aggiornamento.Ovviamente le altre operazioni, come l'eliminazione,vengono effettuate allo stesso modo. Anche il metodogetMetaData risulta in questo frangente molto utile, inquanto consente di ottenere dinamicamente informazioni dialto livello relative al risultato, cosa non possibile conResultSet (richiede la conoscenza di nome, numero e tipo dicolonne per poter processare la tabella): a questo propositoesiste la classe ResultSetMetaData, che permette dideterminare numero, nomi e tipi di colonne nel ResultSet.Terminata l'elaborazione, si chiude la connessioneesplicitamente con:
connection.close();