Java 04
-
Upload
davide-ficano -
Category
Technology
-
view
2.180 -
download
2
Transcript of Java 04
Diapositiva 1
Java
JDBCAccesso al database
Davide [email protected]
Cosa JDBC
JDBC significa Java Database Connectivity
Standard definito da Sun MicroSystems per connettere programmi Java ai database relazionali
E' costituito da un insieme di classi e interfacce scritte in Pure Java
Si basa sul concetto di driver di database
Il driver una implementazione JDBC specifica per database
Permette ai diversi fornitori di database di estendere lo standard con i loro specifici driver JDBC (Oracle, MySQL, MS SQL Server)
Cosa fa JDBC
Stabilisce una connessione con il database
Invia comandi SQL
Processa il risultato
Come si usa JDBC
Import dei package java.sql.*
Registrazione del driver (Oracle, MySQL)
Apertura connessione
Creazione oggetto Statement
Esecuzione query e recupero dati dal ResultSet
Utilizzo ResultSet
Chiusura risorse ResultSet e Statement
Chiusura connessione
I passi da eseguire
DriverManager
Driver
Connection
Statement
ResultSet
JDBC
Registrazione Driver
Per utilizzare un driver di database un'applicazione lo deve rendere disponibile applicazione (si chiama registrazione del driver)
Questo si fa ad esempio come prima istruzione del metodo main
public static void main(String[] args) throws Exception { Class.forName(JDBC_DRIVER).newInstance(); ... ...}
Nell'esempio JDBC_DRIVER e' un stringa contenente il nome del driver
JDBC
Apertura connessione /1
La classe java.sql.DriverManager permette di creare connessioni
I metodi per creare una connessione sono
getConnection(String url, String user, String password) throws SQLException
Tenta di stabilire una connessione tramite una URL utilizzando user e password
getConnection(String url) throws SQLException
Tenta di stabilire una connessione tramite una URL
L'overload del metodo con un solo paramentro permette di passare user e password direttamente sulla URL
Tutti i metodi di JDBC lanciano l'eccezione java.sql.SQLException
JDBC
Apertura connessione /2
Una connessione rappresenta una sessione con uno specifico db
Le sessioni sono risorse preziose in un db e bisogna gestirle con cura
Si possono avere pu connessioni contemporanee con il db
E' possibile ottenere informazioni sulla struttura del db (metadata)
E' possibile gestire le transazioni
In JDBC spesso si usano i connection pool per ottimizzare gli accessi alle connessioni
La URL JDBC
La URL contiene varie informazioni
macchina (e porta) dove gira il database
nome dell'istanza del database
Cambia per ogni database (Oracle, MySQL)
jdbc:oracle:thin:[user/password]@[host][:port]:SID
jdbc:mysql://[host]:[po]/[dbname]
Viene usato lo pseudo protocollo jdbc:
Eseguire uno statement
Il codice mostrato
ottiene una connessione ad database (linea 2)
esegue uno statement di select (linea 5)
public void eseguiSelect() throws SQLException {
Connection conn = DriverManager
.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
Statement st = conn.createStatement();
st.executeQuery("select * from Animale");
st.close();
conn.close();
}
Interfaccia
java.sql.Statement
Viene usato il metodo Connection.createStatement per
ottenere una interfaccia JDBC per eseguire istruzioni SQL statiche
Una istruzione si dice statica quando non ci sono variabili JDBC che modificano la query
st.executeQuery("select * from Animale where nome = 'Fido'");
La condizione di where statica se il nome cambia dovrei costruire la query in modo diverso, ad esempio concatenando la stringa
st.executeQuery("select * from Animale where nome = '" + nome + "'");
Alcuni metodi dell'interfaccia
java.sql.Statement
execute(Stringsql)
Esegue una espressione SQL che pu ritornare risultati multipli
executeQuery(Stringsql)
Esegue una espressione SQL che ritorna un solo oggetto ResultSet
executeUpdate(Stringsql)
Esegue una espressione SQL che pu essere: INSERT, UPDATE, or DELETE
Perch tutti questi metodi cos simili?
Per sfruttare le ottimizzazioni del database
il programmatore sa cosa vuole e richiama il metodo pi appropriato
Interfaccia
java.sql.ResultSet
Un ResultSet fornisce l'accesso ai dati di una tabella generati eseguendo uno Statement
Si pu aprire un solo ResultSet alla volta
Il ResultSet mantiene un cursore alla riga corrente ottenuta dal database
Alcuni metodi di
java.sql.ResultSet
java.sql.Date getDate(intcolumnIndex)
double getDouble(intcolumnIndex)
int getInt(intcolumnIndex)
String getString(intcolumnIndex)
Il parametro in ingresso, columnIndex, indica la posizione del campo nella select
E' possibile passare il nome del campo anzich la posizione
java.sql.Date getDate(StringcolumnName)
Chiusura risorse
Si e' detto che le connessioni sono risorse preziose per cui vanno rilasciate appena possibile
Lo stesso vale per Statement e ResultSet
La chiusura avviene utilizzando il metodo close()
Connection.close()
Statement.close();
ResultSet.close();
Esempio di select completo
private void stampaNomi(Connection conn) throws SQLException {
String query = "select nome from Animale order by nome";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
String nome = rs.getString("nome");
System.out.println("Nome = " + nome);
}
rs.close();
st.close();
}
Esercizio /1
SELECT JDBC
Sul database sono presenti due tabelle gia' popolate
Scrivere un programma che
stampi i nomi ed il tipo di animale uno per riga
L'output atteso e' mostrato in Figura
Nome = fido descrizione = canideNome = polly descrizione = uccelloNome = silvestro descrizione = felinoNome = titty descrizione = uccello
Non solo select /1
Statement.executeUpdate
Quando si vuole eseguire una INSERT su database si deve usare executeUpdate
private void inserisciCavalli(Connection conn) throws SQLException {
Statement st = conn.createStatement();
st.executeUpdate("insert into animale (nome, fk_tipo) values ('furia', 'cavallo');");
st.executeUpdate("insert into animale (nome, fk_tipo) values ('fulmine', 'cavallo');");
st.close();
}
Non solo select /2
executeUpdate
executeUpdate viene usato anche per UPDATE e DELETE
E' possibile conoscere quanti record sono stati interessati dall'operazione di UPDATE/DELETE utilizzando il valore ritornato
private void eliminaCavalli(Connection conn) throws SQLException {
Statement st = conn.createStatement();
int count;
count = st.executeUpdate("delete from animale where fk_tipo = 'cavallo'");
System.out.println(String.format("Eliminati %d cavalli", count));
st.close();
}
Esercizio /2
UPDATE JDBC
Scrivere un programma che permetta di rinominare un animale
Il metodo renameAnimale deve prendere 4 argomenti
connessione
nuovo nome
vecchio nome
tipo animale
Stampare un messaggio che indichi se l'operazione ha avuto successo
Quando l'operazione ha avuto successo?
Indipendenza dal database /1
Le query che abbiamo visto contengono le stringhe che intendiamo usare
nelle clausole WHERE
nei valori delle INSERT
Ma cosa succede se le stringhe hanno caratteri particolari? Ad esempio apici o doppie virgolette
Indipendenza dal database /2
La soluzione e' quella di fare l'escape ma
questo e' un compito oneroso per il programmatore
ogni database ha regole diverse
Oracle usa gli apici per definire una stringa
MySql usa anche le doppie virgolette
"select * from Animale where nome = '" + nome + "'""delete from animale where fk_tipo = 'cavallo'""insert into animale (nome, fk_tipo) values ('furia', 'cavallo');"
Indipendenza dal database /3
Il lavoro di escape deve essere fatto dal driver JDBC
Ogni driver conosce le proprie regole (Oracle sa come fare l'escape delle proprie stringhe)
le differenze non riguardano solo le stringhe, possono coinvolgere anche
numeri interi
numeri in virgola mobile
ma soprattutto le date (ogni database ha un suo formato per definire una data ad esempio in una clausola WHERE)
Il codice di accesso al DB viene scritto una sola volta
Indipendenza dal database /3
Connection.PreparedStatement
Per risolvere il problema e' sufficiente utilizzare la classe PreparedStatement al posto di Statement
Non si usa il metodo Connection.createStatement ma Connection.prepareStatement
I valori da associare vengono sostituiti con il carattere punto interrogativo
Per impostare i parametri si usano i metodi
setString / setDate / setXXX
Indipendenza dal database /4
Connection.PreparedStatement
Differenze di codifica tra createStatement...
String sql = "select a.nome from ANIMALE a, TIPO_ANIMALE t"
+ " where a.fk_tipo=t.tipo"
+ " and t.tipo=?"; // con ? si definisce un parametro
PreparedStatement st = conn.prepareStatement(sql); // riceve la query
st.setString(1, tipoAnimale);
ResultSet rs = st.executeQuery();
String sql = "select a.nome from ANIMALE a, TIPO_ANIMALE t"
+ " where a.fk_tipo=t.tipo"
+ " and t.tipo='" + tipoAnimale + "'";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql); // executeQuery riceve la query
... e prepareStatement
Esercizio /3
Utilizzare PreparedStatement
Modificare il codice di renameAnimale in modo che funzioni con PreparedStatement
Oggetti VO e DAO
La scrittura di codice java per l'accesso al database e' stata razionalizzata dividendo logicamente il codice
Vengono create due gerarchie di classi contenenti
Oggetti che rappresentano la struttura della tabella
Oggetti che effettuano SELECT/INSERT/UPDATE/DELETE
Questa classificazione non e' obbligatoria ma agevola la suddivisione in gerarchie ben definite
Oggetti VO /1
Value Object
Un value object e' una rappresentazione Java di una tabella
Per la tabella ANIMALE esistera'
la classe Animale
Per la tabella TIPO_ANIMALE esistera'
la classe TipoAnimale
Le classi altro non sono che dei bean
con getter e setter (non hanno logica)
Oggetti VO /2
Value Object
public class Animale {
private String nome;
private String tipo;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTipo() {
return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;
}
}
Oggetti DAO /1
Data Access Object
Queste classi interagiscono con il database e utilizzano i VO
La connessione viene passata al costruttore oppure ai singoli metodi
Per la tabella ANIMALE esistera' una classe AnimaleDAO
L'output di un DAO (se presente) dovrebbe essere sempre del tipo della tabella che rappresenta
Eventuali JOIN tra piu' tabelle diventano dettagli implementativi
Oggetti DAO /2
Data Access Object
public class AnimaleDAO {
public List ricercaByTipo(Connection conn, String tipoAnimale)
throws SQLException {
... // il codice che crea il PreparedStatement e' stato omesso
List list = new ArrayList();
while (rs.next()) {
Animale a = new Animale();
a.setNome(rs.getString(1));
a.setTipo(tipoAnimale);
list.add(a);
}
return list;
}
}
Esercizio /4
VO e DAO
Creare gli oggetti VO e DAO per Animale
Creare i metodi utilizzando il pattern VO/DAO per
Cercare per nome e per tipo
Inserire un nuovo animale
Rinominare un Animale
Cancellare un Animale
03/03/09