JDBC (Java DataBase Connectivity) | |||
Mer 07 Nov 2007 |
|
Introduzione
JDBC (Java DataBase Connectivity) è una API che consente ad un qualsiasi programma scritto in java di accedere ad un qualsiasi DBMS (JDBC è simile a ODBC, JDBC è specifico per i programmi scritti in java mentre ODBC si può usare indipendentemente dal linguaggio utilizzato). Le API JDBC si trovano all'interno del package java.sql, all'interno di questo package sono definite classi ed interfacce che consentono di effettuare diverse operazioni sul database- connessione al database;
- esecuzione di istruzioni SQL: INSERT, UPDATE, DELETE, SELECT, eccetera;
- La classe DriverManager;
- L'interfaccia Connection;
- L'interfaccia Statement;
- La classe ResultSet;
- L'implementazione del driver, che dovrà essere conforme alle specifiche delle API java.sql, realizzata dal produttore del DBMS. Questa implementazione consisterà nell'implementazione dei vari metodi delle interfacce e delle classi costituenti il package java.sql.
- L'implementazione dell'applicazione da parte del programmatore.
JDBC Driver
Esistono driver per molti database, i driver vengono classificati in 4 categorie- JDBC-ODBC bridge. Il driver utilizza ODBC, ogni chiamata a JDBC viene tradotta in una chiamata a ODBC.
- driver API nativo. Converte le chiamate a JDBC in chiamate alle API del database.
- protocollo di rete.
- protocollo nativo.
Connessione al DBMS
Un esempio di codice per la connessione con un DBMS è il seguentetry {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//si carica il driver
}
catch (ClassNotFoundException exc)
{
System.out.println("Errore: Driver jdbc non presente "+exc.getMessage());
}
try {
String url="jdbc:odbc:basedati";//si specifica l'url del database
String user = "utente";
String passwd = "password";
Connection con = DriverManager.getConnection(url, user, passwd);
...
}
catch (SQLException exc1)
{
System.out.println("Errore nella Connessione" +exc1.getMessage());
}
Innanzitutto si carica il driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"), quindi si effettua la connessione specificando i dati dell'utente (nome e password) e l'url. In questo esempio si è utilizzato il driver sun.jdbc.odbc.JdbcOdbcDriver, in generale si può usare un qualsiasi altro driver a seconda del database a cui ci si deve connettere.
L'url ha la forma seguente jdbc:<subprotocol>:<subname>, dove
-
<subprotocol> è il nome del driver o del meccanismo
che si usa per connettersi al database. Nell'esempio proposto si usa un bridge JDBC:ODBC
String url="jdbc:odbc:basedati";
- <subname> identifica la sorgente dei dati.
Lettura Dati dal DB
Si supponga di avere una tabella del tipoTabella(
Cognome Char(20),
Nome Char(20),
Provincia Char(20),
Nazione Char(20),
Luogodinasc Char(20),
Datadinasc Char(20),
primary key(....)
)
per poter estrarre dati da questa tabella (accesso in lettura) si procede nel seguente modo
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException exc)
{
System.out.println("Errore: Driver jdbc non presente "+exc.getMessage());
}
try {
String url="jdbc:odbc:dati";
String user = "utente";
String passwd = "password";
Connection con = DriverManager.getConnection(url, user, passwd);
Statement Tabella = con.createStatement();
ResultSet r = Tabella.executeQuery("SELECT * FROM Tabella WHERE "+
"(Cognome ='cognome+') and (Nome = '"+nome+"')");// si esegue la query
if (r.next())
{// se la query produce almeno una riga allora ....
Data = r.getString("Datadinasc");
luogo = r.getString("Luogodinasc");
nazione = r.getString("Nazione");
citta = r.getString("Provincia");
}
}
catch (SQLException exc1)
{
System.out.println("Errore nell'Inserimento dei Dati" +
exc1.getMessage());
}
I passi da seguire sono quindi i seguenti
-
Si carica il driver
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException exc)
-
Si effettua la connessione con il database
String url="jdbc:odbc:dati";
String user = "utente";
String passwd = "password";
Connection con = DriverManager.getConnection(url, user, passwd);
-
Si crea un oggetto Statement
Statement Tabella = con.createStatement();
- Si crea un oggetto ResultSet, in cui saranno posti i risultati della query
-
Si effettua la query tramite l'istruzione Tabella.executeQuery("....").
In questo modo si specifica che la query si svolge nell'ambito della statement
Tabella
ResultSet r = Tabella.executeQuery("SELECT * FROM Tabella WHERE "+
"(Cognome ='cognome+') and (Nome = '"+nome+"')");// si esegue la query
- Si verifica se la query ha prodotto dei risultati (righe
della tabella che soddisfano le condizioni specificate
nella query). Se ha prodotto dei risultati si effettuano le
operazioni sui dati. La verifica viene effettuata tramite
r.next() (r.next()
restituisce il valore booleano true se nel ResultSet
r esiste una riga dopo la riga corrente)
if (r.next())
{// se la query produce almeno una riga allora ....
Data = r.getString("Datadinasc");
luogo = r.getString("Luogodinasc");
nazione = r.getString("Nazione");
citta = r.getString("Provincia");
}
Inserimento Dati nel DB
Si supponga di avere una tabella del tipoTabella(
Cognome Char(20),
Nome Char(20),
Provincia Char(20),
Nazione Char(20),
Luogodinasc Char(20),
Datadinasc Char(20),
primary key(....)
)
per poter inserire dati in questa tabella (accedere in scrittura) si procede nel seguente modo
try {
String url="jdbc:odbc:dati";
String user = "utente";
String passwd = "password";
/* si crea la Connessione con il database */
Connection con = DriverManager.getConnection(url, user, passwd);
con.setAutoCommit(false);
/* con questa istruzione si fa in modo che il commit avvenga solo se esplicitamente invocato dall'utente*/
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement dati = con.createStatement();// si crea un oggetto Statement
String insert = "INSERT INTO Tabella VALUES ('"+cognome+
"', '"+nome+"', '"+provincia+ "', '"+ nazione + "', '" +luogodinasc+
"', '"+datadinasc+"'))";// si forma l'operazione di insert
Tabella.executeUpdate(insert);// si esegue l'operazione di insert
con.commit();// si effettua il commit
Tabella.close();// si chiude lo Statement Tabella
con.setAutoCommit(true);// si ripristina l'autocommit
con.close();//si chiude la connessione
}
catch (SQLException exc1)
{
System.out.println("Errore nell'inserimento dei dati "
+exc1.getMessage());
}
I passi da seguire sono quindi i seguenti
- Si carica il driver
- Si effettua la connessione con il database
- Si disabilita l'autocommit. In questo modo il commit
sarà fatto solo su indicazione dell'utente e
non automaticamente dal DBMS
/* si crea la Connessione con il database */
Connection con = DriverManager.getConnection(url, user, passwd);
con.setAutoCommit(false);
-
Si imposta il grado di isolamento delle transazioni
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
in questo esempio si imposta il livello che garantisce la massima integrità dei dati. Le transazioni sono serializzate, vengono eseguite una di seguito all'altra. -
Si crea un oggetto Statement
Statement dati = con.createStatement();// si crea un oggetto Statement
-
Si esegue l'operazione di INSERT tramite l'istruzione
Tabella.executeUpdate(insert).
In questo modo si specifica che l'inserimento si svolge
nell'ambito dello statement Tabella
String insert = "INSERT INTO Tabella VALUES ('"+cognome+
"', '"+nome+"', '"+provincia+ "', '"+ nazione + "', '" +luogodinasc+
"', '"+datadinasc+"'))";// si forma l'operazione di insert
Tabella.executeUpdate(insert);// si esegue l'operazione di insert
-
Si effettua il commit
con.commit();// si effettua il commit
-
Si chiude lo Statement
Tabella.close();// si chiude lo Statement Tabella
-
Si ripristina l'autocommit
con.setAutoCommit(true);// si ripristina l'autocommit
-
Si chiude la connessione
con.close();//si chiude la connessione
I Trigger
I trigger sono delle soubroutine che è possibile invocare quando si verificano particolari condizioni sulla base di dati. Ad esempio si potrebbe realizzare una soubroutine che controlli tutte le righe che si vogliono inserire in una tabella e consenta di inserire una riga nella tabella solo se questa soddisfa determinate condizioni.L'uso dei trigger varia da DBMS a DBMS, qui si vedrà l'uso con Oracle. Per creare un trigger si procede nel seguente modo
- si crea una classe Java;
- si attacca la classe Java ad una tabella;
- si crea il Trigger;
ALTER TABLE Tabella ATTACH JAVA CLASS "check" IN 'c:\tmp\classes';
.
/
In questo modo si specifica che alla tabella Tabella deve essere attaccata la classe check che si trova in c:\tmp\classes. Per creare il relativo Trigger si procede nel seguente modo
CREATE TRIGGER trigger
AFTER INSERT ON Tabella
FOR EACH ROW "check1" (new.campo1, new.campo2);
.
/
In cui si specifica che il trigger è costituito dalla soubroutine check1 presente nella classe check, deve essere invocato dopo l'inserimento di una riga nella tabella. E i parametri che riceve la soubroutine devono essere i campi campo1 e campo2 della tabella. La classe check è la seguente
check.java
import java.sql.*;
class check
{
public void check1 (Connection con, String campo1, String campo2)
throws SQLException
{
String inizio, fine;
boolean violazione = false;
Statement s = con.createStatement();
ResultSet r = s.executeQuery("SELECT * FROM Tabella WHERE (Cognome = '"+
campo1 +"') and (Nome = '"+ campo2+ "')");
while (r.next())
{
inizio = r.getString("Inizio");
fine = r.getString("Fine");
if ((parsedata.After(data1,inizio)&&parsedata.Before(data1,fine)) ||
(parsedata.After(data2,inizio)&&parsedata.Before(data2,fine)))
violazione = true;
}
s.close();
if (violazione)
{
System.out.println("Vincolo Violato");
throw new SQLException("");
}
}
.............// eventuali altri metodi
}
Il formato del comando ALTER TABLE è il seguente
ALTER TABLE <schema>.<tabella>
ATTACH JAVA {SOURCE | CLASS} "classe"
WITH CONSTRUCTOR ARGS (lista_parametri)
una volta attaccata la classe Java per staccarla si utilizza il comando
ALTER TABLE <schema>.<tabella>
DETACH [AND DELETE] JAVA CLASS "classe"
Da notare che per eliminare la classe si deve utilizzare il comando
ALTER TABLE <schema>.<tabella>
DETACH AND DELETE JAVA CLASS "classe"
se non si usasse il termine AND DELETE la classe sarebbe staccata dalla tabella, ma non sarebbe cancellata. Il formato del comando CREATE TRIGGER è il seguente
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER} [{INSERT | DELETE | UPDATE [OF (listacampi)]}]
ON Tabella FOR EACH ROW soubroutine_name(listadiargomenti)
Il trigger può essere attivato prima o dopo {BEFORE| AFTER} un'operazione; l'operazione può essere INSERT, DELETE o UPDATE. Da notare che si possono usare solo le combinazioni BEFORE - {......} e AFTER - {........}