Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
Fondamenti di JDBC
Concetto di driver
Il dialogo fra applicazione e DBMS non è mai gestito direttamente ma passa in genere per un
opportuno modulo software chiamato driver che agisce da interfaccia fra il client e il DBMS
(Database Management System) stesso. In “origine” la comunicazione fra applicativo e
database era piuttosto difficoltosa: c'era infatti bisogno di un driver specifico, cioè di una API
(Application Program Interface) specifica e proprietaria, per poter accedere ad ogni diverso
database.
Fig. 1 – Situazione alle “origini”
ODBC (Open Database Connectivity) Driver
Nel 1991, Microsoft progettò Open Database Connectivity (ODBC), una API standard per la
connessione ai DBMS. In tal modo, i programmi, attraverso questo strato software comune,
potevano connettersi a diversi tipi di database utilizzando le funzioni standard disponibili nella
API e il codice SQL (Structured Query Language). La prima versione è stata sviluppata su
Windows in linguaggio C e consiste di una dll (dynamic link library); altre release sono state
scritte per Unix, OS/2 e Macintosh.
Fig. 2 – Driver ODBC
jdbc-parte1.pdf
Pag. 1/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
Nella fig. 2 non sono evidenziati i driver proprietari dei singoli database. ODBC genera
automaticamente richieste che il sistema di database è in grado di capire.
JDBC-ODBC Bridge
Successivamente, Sun Microsystems, in attesa di una soluzione “pure Java 100%”, introdusse
una API intermedia tra ODBC e l'applicazione denominandola JDBC-ODBC Bridge (tipo 1).
Fig. 3 – Driver “ponte” JDBC-ODBC
Il driver converte le chiamate ai metodi JDBC-ODBC in chiamate a funzioni ODBC.
Il driver è implementato nella classe jdbc.odbc.JdbcOdbcDriver ed è fornito con Java 2 SDK
Standard Edition.
JDBC Driver
JDBC (Java DataBase Connectivity) (tipo 4) è una API per database interamente scritta in java
localizzata nel package java.sql. JDBC API fornisce metodi e interfacce per interrogare e
modificare i dati ed è Object Oriented. La piattaforma Java 2 Standard Edition contiene le API
JDBC, insieme all'implementazione di un bridge JDBC-ODBC, che permette di connettersi a
database relazionali che supportano ODBC (per esempio Access).
Fig. 4 – Driver JDBC
jdbc-parte1.pdf
Pag. 2/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
Il problema
Vogliamo progettare una applicazione java “console” che ci consenta di ottenere l'elenco dei
libri scritti da un certo autore di cui è nota l'anagrafica (nome e cognome). Si tratta di un
esempio già trattato in altre esercitazioni, in particolare si veda l'articolo “Database a oggetti:
db4o”, l'esercitazione “Prototipo applicazione Biblioteca”, l'articolo “DAO-Data Access Object”
reperibili nella sezione Java, http://www.mauriziocozzetto.it.
Ipotizziamo che gli autori, i libri e le case editrici debbano essere memorizzati in un database
MySQL (biblio_db) e che per semplicità un libro possa essere scritto da un solo autore (nella
realtà un libro può essere scritto a più mani), mentre una casa editrice può pubblicare più libri.
Il modello dei dati
Fig. 5 – Diagramma E-R (Entity-Relationship)
Il modello a oggetti
La classe DAO (Data Access Object) fungerà da strato software di accesso al database.
Le tre classi fondamentali Autore, Libro ed Editore “mapperanno” le tre tabelle autori_tbl,
libri_tbl ed editori_tbl.
Fig. 6 – Struttura delle classi di base dell'esercitazione
jdbc-parte1.pdf
Pag. 3/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
Preparazione dell'ambiente di lavoro
Xampp (Windows/Linux)
Xampp è un ottimo tool che fornisce allo sviluppatore in un unico pacchetto un server web
(Apache2) dotato dell'estensione per il Php e un server MySQL, oltre ad altri strumenti come
PhpMyAdmin, Mercury (un server di posta) ecc. Possiamo installarlo sia in ambiente Windows
che Linux: maggiori dettagli per l'installazione, sono reperibili sul sito http://www.xampp.org.
Per attivarlo possiamo usare in ambiente Windows l'apposita icona presente sul Desktop o
lanciare il demone (in ambiente Linux Ubuntu) mediante il comando
sudo /opt/lampp/lampp start
Per arrestare il servizio procediamo in maniera analoga cliccando due volte sull'icona di arresto
del servizio (Windows) o mediante il comando
sudo /opt/lampp/lampp stop
(Linux Ubuntu). In alternativa possiamo sempre decidere di installare e configurare sulla
nostra macchina i 3 servizi in maniera distinta, facendo attenzione a configurare correttamente
i 3 programmi e l'ambiente di lavoro nel suo complesso. Ricordiamo che una volta attivo, il
server Web Apache2 rimane in ascolto sulla porta 80 della nostra macchina e che MySQL
rimane invece in ascolto sulla porta 3306. Xampp è ottimo per il test delle applicazioni ma
è sconsigliato in produzione (ad esempio MySQL dispone del solo utente root senza password).
PhpMyAdmin (Xampp)
Prepariamo, usando l'utility PhpMyAdmin, la struttura delle tre tabelle autori_tbl, editori_tbl e
libri_tbl (nell'ordine in figura).
Fig. 7 – Struttura delle 3 tabelle autori_tbl, editori_tbl e libri_tbl
jdbc-parte1.pdf
Pag. 4/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
In quest'ultima tabella (libri_tbl) , i campi idAutore e idEditore fungono da chiavi esterne.
Inizialmente le tre tabelle libri_tbl, autori_tbl ed editori_tbl non contengono dati. Inseriamo
poi alcuni dati di prova usando PhpMyAdmin.
I Driver JDBC di MySQL
Una volta costruito il database, dobbiamo procurarci i driver nativi Java MySQL, chiamati
MySQL Connector/J
(http://dev.mysql.com/downloads/connector/j/5.1.html). Dal pacchetto scaricato
mysql-connector-java-5.1.6.tar.gz
preleviamo il file
mysql-connector-java-5.1.6-bin.jar
e copiamolo (o spostiamolo) in un package del nostro progetto. Ricordiamo tuttavia che nelle
versioni più recenti di NetBeans (ad esempio nella versione 6.1), questi driver sono già
installati: occorre solo aggiungerli al progetto (tasto destro del mouse sul progetto >
Properties > Libraries > Add Library ... > MySQL JDBC Driver)
I driver JDBC-ODBC di Access (Windows)
In alternativa a Xampp, possiamo sempre preparare un database in Access e costruire
(mediante il Pannello di Controllo > Strumenti di Ammnistrazione > Origine dati JDBC-ODBC >
(Scheda DSN) Aggiungi... > DSN (Data Source Name)) un alias che identifica in modo univoco
la “fonte dati”.
Riepilogo principali metodi e interfacce JDBC
Caricamento dei driver
// Per un database MySQL
String driver = “ com.mysql.jdbc.Driver”;
// Il metodo forName forza il caricamento del driver
Class.forName(driver); // lancia una ClassNotFoundException
// Se il database è Oracle, allora
// String driver = “oracle.jdbc.OracleDriver”;
// Se il driver è JDBC-ODBC (tipo 1), allora
// String driver = “sun.jdbc.odbc.JdbcOdbcDriver”;
// Se il database è PostgresQL, allora
// String driver = “com.postgresql.Driver”;
Creazione della connessione
// Per un database MySQL
String url = "jdbc:mysql://localhost:3306/biblio_db”;
// Xampp non definisce una password per l'utente root
// si consiglia di impostare una password in produzione
String username=”root”;
String password = “”;
jdbc-parte1.pdf
Pag. 5/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
// Connection è un'interfaccia, getConnection() un metodo statico della classe DriverManager
Connection conn = DriverManager.getConnection(url, username, password);
// lancia una SQLException
// username e password sono opzionali
// se il database è Oracle di tipo thin, allora
// String url =” jdbc:oracle:thin:@//localhost:1521/biblio_db“;
//
//
//
//
se il driver è JDBC-ODBC (tipo1), la url è
String url = “jdbc:odbc:biblio_db”;
biblio_db è il DSN (Data Source Name)
(di solito si crea nei sistemi Windows mediante il Pannello di Controllo)
// Se il database è PostGreSQL, allora
// String url = “jdbc:postgresql://localhost:5432/biblio_db”;
Preparazione dell'istruzione SQL
// L'oggetto st rappresenta l'istruzione SQL
// Statement è un'interfaccia
Statement st = conn.createStatement();
// lancia una SQLException
Esecuzione della query (query di lettura)
String sql = “SELECT * FROM editori_tbl”;
// ResultSet è un'interfaccia
ResultSet rs = st.executeQuery(sql); // lancia una SQLException
// rs contiene le righe della tabella
Il cursore (puntatore al record corrente) adesso è posizionato prima della prima riga
Per spostare il cursore in avanti, indietro ecc, possiamo usare i seguenti metodi (booleani):
next(), previous(), first(), last(), beforeFirst(), afterLast() ecc
Lettura di tutti i record
while (rs.next()) {
// idEditore è il nome della prima colonna della tabella
int idEditore= rs.getInt("idEditore");
// nomeEditore il nome della seconda colonna della tabella
String nomeEditore = rs.getString("nomeEditore");
// oppure
// int idEditore= rs.getInt(1);
// 1 è la posizione della prima colonna
// ...
// elaborazione dei campi
} // fine while
Aggiornamento dei record
Qualora si voglia effettuare un aggiornamento dei record con le istruzioni SQL INSERT,
UPDATE, DELETE (ma anche CREATE), possiamo usare il metodo executeUpdate che restituisce
il numero dei record aggiornati in caso di successo.
// elimina i record che soddisfano al criterio specificato
String url =”DELETE FROM editori_tbl WHERE idEditore = 100”;
int result = st.executeUpdate(sql); // lancia una SQLException
jdbc-parte1.pdf
Pag. 6/7
Cozzetto ©
Laboratorio di Sistemi
Fondamenti di JDBC (parte1)
Java
if (result>0) {
// tutto ok
} else {
// Impossibile cancellare il(i) record
}
Query parametriche
// troviamo gli editori milanesi
// Il ? rappresenta il parametro
Sring sql = "SELECT * FROM editori_tbl WHERE cittaEditore = ?";
String citta = "Milano";
// Interfaccia PreparedStatement
PreparedStatement ps = conn.prepareStatement(sql);
// Associamo al (primo e unico) parametro la stringa citta
ps.setString(1, citta);
// eseguiamo la query
ResultSet rs = ps.executeQuery();
// nessun argomento per il metodo executeQuery, attenzione!
// si possono scorrere i record come descritto precedentemente
while (rs.next()) {
//lettura ed elaborazione dei record
// ...
}
Chiusura degli oggetti
// gli oggetti vanno chiusi correttamente nell'ordine inverso a quello di apertura.
ps.close();
// lancia una SQLException
rs.close();
// idem
st.close();
// idem
conn.close(); // idem
jdbc-parte1.pdf
Pag. 7/7
Cozzetto ©