|
Cominciamo adesso ad entrare nei dettagli tecnici
relativi alla realizzazione del catalogo. La connessione a database
è realizzata utilizzando lo standard di Java per l'accesso a
database denominato JDBC. Grazie a questo standard è
possibile scrivere programmi in Java che utilizzano database di
tipo diverso senza doverli riscrivere ogni volta. Infatti i
dettagli specifici della connessione ad un tipo di database sono
incapsulati in un driver. In figura
3 possiamo vedere l'architettura del JDBC.
Figura 3
Abbiamo un DriverManager che
serve da interfaccia con i driver veri e propri. I driver a loro
volta si collegano a database in vari modi. Alcuni si collegano
semplicemente ad un database locale, altri invece possono
utilizzare la rete per connettersi a database remoti. Java non
fornisce i driver dei singoli database, solamente il
DriverManager: per accedere ad uno
specifico database occorre procurarsi un driver apposito che
solitamente viene fornito dal produttore. Nel caso del DB/2 di
AS/400, caso il driver che ci consente la connessione all'AS/400
è compreso nell'AS/400 Toolbox, ed è
com.ibm.as400.access.AS400JDBCDriver.Nel caso di MySQL è
org.gjt.mm.mysql.Driver. E' importantenotare che cambiando il driver generalmente è
possibile utilizzare un database completamente diverso senza dover
modificare il codice. In realtà occorre ricorrere nelle
query ad un SQL abbastanza standard, ma se si utilizza un minimo di
criterio e si pone un occhio agli standard la portabilità
delle applicazioni è abbastanza alta. Non è garantita
al 100% perché purtroppo ogni database pur conforme a SQL
è leggermente diverso dagli altri a volte in maniera
subdola. Generalmente si riesce comunque ad utilizzare un SQL
standard per quanto riguarda interrogazioni, inserimenti e
modifiche.
Come abbiamo accennato, un aspetto importante del
JDBC e fondamentale ai nostri fini è il fatto che è
progettato per la connessione a database remoti accessibili via
rete. Le applicazioni Java si connettono al database passando per
un Driver Manager che rappresenta una API standardizzata per le
connessioni a database SQL. La API a sua volta utilizzerà
per effettuare effettivamente la connessione un driver. Questo
driver può essere scritto in modo da utilizzare un database
locale: per esempio una applicazione Java sotto Windows riesce ad
utilizzare qualsiasi file di database locale accessibile via
ODBC. Ma l'aspetto più interessante è che la stessa
API consente l'accesso a database remoti per i quali sia
stato fornito il driver. In particolare è possibile accedere
ad un database AS/400 da una applicazione Web che si trova a girare
in un altro computer possibilmente distante migliaia di chilometri.
L'aspetto interessante di tutto il discorso è osservare come
in un caso tipico un utente di Palermo può consultare un
sito Web il cui server è a Roma e che utilizza un database
AS/400 che si trova a Milano.
Esaminiamo adesso in codice come sia possibile
utilizzare il database. Il primo passo è quello di caricare
il driver specifico, con:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
Nel primo caso ci si riferisce al driver per la
connessione ad un database locale via ODBC (per macchine Windows e
alcuni Unix), nel secondo al driver per la connessione ad un
database AS400 remoto. In generale una volta individuato un driver
si deve solamente specificare il database da usare. Ma
poiché ci si può connettere contemporaneamente a
diversi database, di tipo diverso e localizzati su computer
distinti, Java utilizza per la localizzazione dei dati da
utilizzare una stringa simile agli URL del Web. Pertanto la fase di
connessione richiede la creazione di un oggetto Connection che utilizza come parametro un "jdbc URL",
come segue:
getConnection("jdbc:odbc:db","user","pass")
getConnection("jdbc:as400://as.ditta.it/db","user","pass")
Anche in questo caso il primo URL si riferisce a un
database locale accessibile via ODBC, e il secondo ad un database
remoto accessibile via rete. Se esaminiamo il formato di questo
URL, potremo notare come la prima parte sia un prefisso comune
(jdbc:) che serve a distinguere il tipo di
URL dagli altri disponibili (come http:,ftp:, rmi: eccetera); segue una stringa che specifica il
tipo di driver da utilizzare (odbc, as400). L'ultima parte serve a localizzare il
database. In casi più semplici come quelli relativi ai
database locale, basta il nome. Per essere corretti nel caso di
ODBC il nome del database si riferisce al DSN (Data Source Name) di
ODBC che viene specificato nel pannello di controllo quando si
aggiunge una nuova fonte dati. Invece nel caso dell'AS400, che
è una connessione di rete, occorre specificare l'indirizzo
Internet o Intranet dove si trova il server, seguito dal nome del
database. Nel caso dell'AS/400 il nome del database è
più propriamente il nome di una collezione di tabelle creata
sul server.
Fin qui abbiamo visto come fare a creare la
connessione. Occorre adesso vedere come eseguire interrogazioni sul
database. Ogni operazione di interrogazione viene eseguita in 3
passi:
-
Crezione del comando
(statement)
-
Esecuzione della interrogazione
(query)
-
Estrazione dei dati risultanti
(result set)
Il codice tipico per l'esecuzione di una
interrogazione è il seguente (le parti in grassetto devono
essere sostituite dalle informazioni specifiche di cui abbiamo
accennato prima, ovvero nome del driver, url per la localizzazione
del database, interrogazioni sql e nomi di campi):
// Creazione della connessione
Class.forName(driver);
Connection con = DriverManager.getConnection(dburl);
// 1. creazione di un comando
Statement stat = con.createStatement();
// 2. esecuzione della interrogazione
ResultSet rs = stat.executeQuery(sql);
// 3. Estrazione dei dati
while(rs.next()) {
// estrazione di un campo
String s = rs.getString(nome-campo-char);
int i = rs.getInt(nome-campo-int)
...
}
Per comprendere appieno il
precedente esempio bisogna puntualizzare che un oggetto
ResulSet si comporta come una tabella
composta di righe; ogni riga è composta di campi, che sono
di tipo diverso (interi e stringhe in primis, ma anche date, float,
blob eccetera). La tabella ha un cursore che inizialmente è
posizionato prima della prima riga;
la posizione del cursore ci permette di accedere ai campi della
riga puntata. Facendolo avanzare (con rs.next()) ci
posizioniamo nelle varie righe del risultato
dal quale possiamo estrarre i valori dei vari campi del risultato
riga con metodi quali rs.getString(nome-campo-char)se
si tratta di una stringa, con
rs.getInt(nome-campo-int)se si tratta di un intero e
così via.
Non abbiamo esaurito il discorso relativo al JDBC
perché ci sono ancora dettagli che esamineremo prossimamente
quando eseguiamo inserimenti in un database. In particolare dovremo
ricorrere ai cosiddetti PreparedStatement, per
l'inserimento, ma per comprendere il funzionamento del catalogo
(che per ora complende solo ricerche) quanto appena detto è
sufficiente.
|