JDBC (Java DataBase Connectivity)
7 Novembre 2007 Database





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 Le classi e le interfacce più importanti sono JDBC è costituito da due componenti

JDBC Driver

Esistono driver per molti database, i driver vengono classificati in 4 categorie

Connessione al DBMS

Un esempio di codice per la connessione con un DBMS è il seguente

  1. try {
  2. Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//si carica il driver
  3. }
  4. catch (ClassNotFoundException exc)
  5. {
  6. System.out.println("Errore: Driver jdbc non presente "+exc.getMessage());
  7. }
  8. try {
  9. String url="jdbc:odbc:basedati";//si specifica l'url del database
  10. String user = "utente";
  11. String passwd = "password";
  12. Connection con = DriverManager.getConnection(url, user, passwd);
  13. ...
  14. }
  15. catch (SQLException exc1)
  16. {
  17. System.out.println("Errore nella Connessione" +exc1.getMessage());
  18. }


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 Nel caso in cui la sorgente dei dati si trovi su un host diverso il subname ha la seguente forma //hostname:port/subsubname

Lettura Dati dal DB

Si supponga di avere una tabella del tipo

  1. Tabella(
  2. Cognome Char(20),
  3. Nome Char(20),
  4. Provincia Char(20),
  5. Nazione Char(20),
  6. Luogodinasc Char(20),
  7. Datadinasc Char(20),
  8. primary key(....)
  9. )

per poter estrarre dati da questa tabella (accesso in lettura) si procede nel seguente modo

  1. try {
  2. Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
  3. }
  4. catch (ClassNotFoundException exc)
  5. {
  6. System.out.println("Errore: Driver jdbc non presente "+exc.getMessage());
  7. }
  8. try {
  9. String url="jdbc:odbc:dati";
  10. String user = "utente";
  11. String passwd = "password";
  12. Connection con = DriverManager.getConnection(url, user, passwd);
  13. Statement Tabella = con.createStatement();
  14. ResultSet r = Tabella.executeQuery("SELECT * FROM Tabella WHERE "+
  15. "(Cognome ='cognome+') and (Nome = '"+nome+"')");// si esegue la query
  16. if (r.next())
  17. {// se la query produce almeno una riga allora ....
  18. Data = r.getString("Datadinasc");
  19. luogo = r.getString("Luogodinasc");
  20. nazione = r.getString("Nazione");
  21. citta = r.getString("Provincia");
  22. }
  23. }
  24. catch (SQLException exc1)
  25. {
  26. System.out.println("Errore nell'Inserimento dei Dati" +
  27. exc1.getMessage());
  28. }

I passi da seguire sono quindi i seguenti

Inserimento Dati nel DB

Si supponga di avere una tabella del tipo

  1. Tabella(
  2. Cognome Char(20),
  3. Nome Char(20),
  4. Provincia Char(20),
  5. Nazione Char(20),
  6. Luogodinasc Char(20),
  7. Datadinasc Char(20),
  8. primary key(....)
  9. )

per poter inserire dati in questa tabella (accedere in scrittura) si procede nel seguente modo

  1. try {
  2. String url="jdbc:odbc:dati";
  3. String user = "utente";
  4. String passwd = "password";
  5.  
  6. /* si crea la Connessione con il database */
  7. Connection con = DriverManager.getConnection(url, user, passwd);
  8. con.setAutoCommit(false);
  9.  
  10. /* con questa istruzione si fa in modo che il commit avvenga solo se esplicitamente invocato dall'utente*/
  11. con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
  12.  
  13. Statement dati = con.createStatement();// si crea un oggetto Statement
  14. String insert = "INSERT INTO Tabella VALUES ('"+cognome+
  15. "', '"+nome+"', '"+provincia+ "', '"+ nazione + "', '" +luogodinasc+
  16. "', '"+datadinasc+"'))";// si forma l'operazione di insert
  17. Tabella.executeUpdate(insert);// si esegue l'operazione di insert
  18. con.commit();// si effettua il commit
  19. Tabella.close();// si chiude lo Statement Tabella
  20. con.setAutoCommit(true);// si ripristina l'autocommit
  21. con.close();//si chiude la connessione
  22. }
  23. catch (SQLException exc1)
  24. {
  25. System.out.println("Errore nell'inserimento dei dati "
  26. +exc1.getMessage());
  27. }

I passi da seguire sono quindi i seguenti

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 Ad esempio sia check.class la classe che si vuole utilizzare, per attaccare alla tabella Tabella la classe si procede nel seguente modo

  1. ALTER TABLE Tabella ATTACH JAVA CLASS "check" IN 'c:\tmp\classes';
  2. .
  3. /

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

  1. CREATE TRIGGER trigger
  2. AFTER INSERT ON Tabella
  3. FOR EACH ROW "check1" (new.campo1, new.campo2);
  4. .
  5. /

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
  1. import java.sql.*;
  2. class check
  3. {
  4. public void check1 (Connection con, String campo1, String campo2)
  5. throws SQLException
  6. {
  7. String inizio, fine;
  8. boolean violazione = false;
  9.  
  10. Statement s = con.createStatement();
  11. ResultSet r = s.executeQuery("SELECT * FROM Tabella WHERE (Cognome = '"+
  12. campo1 +"') and (Nome = '"+ campo2+ "')");
  13.  
  14. while (r.next())
  15. {
  16. inizio = r.getString("Inizio");
  17. fine = r.getString("Fine");
  18. if ((parsedata.After(data1,inizio)&&parsedata.Before(data1,fine)) ||
  19. (parsedata.After(data2,inizio)&&parsedata.Before(data2,fine)))
  20. violazione = true;
  21. }
  22.  
  23. s.close();
  24. if (violazione)
  25. {
  26. System.out.println("Vincolo Violato");
  27. throw new SQLException("");
  28. }
  29. }
  30. .............// eventuali altri metodi
  31. }

Il formato del comando ALTER TABLE è il seguente

  1. ALTER TABLE <schema>.<tabella>
  2. ATTACH JAVA {SOURCE | CLASS} "classe"
  3. WITH CONSTRUCTOR ARGS (lista_parametri)

una volta attaccata la classe Java per staccarla si utilizza il comando

  1. ALTER TABLE <schema>.<tabella>
  2. DETACH [AND DELETE] JAVA CLASS "classe"

Da notare che per eliminare la classe si deve utilizzare il comando

  1. ALTER TABLE <schema>.<tabella>
  2. 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

  1. CREATE [OR REPLACE] TRIGGER trigger_name
  2. {BEFORE | AFTER} [{INSERT | DELETE | UPDATE [OF (listacampi)]}]
  3. 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 - {........}