Ingegneria del Sftware: JDBC laura.bacci@unipv.it
Che csa è JDBC Un insieme di API standard per accedere ai database relazinali Separa e nascnde i dettagli dell specific database all applicazine che l utilizza Parte di J2SE Java SE 6 ha JDBC 4 JDBC: Java DataBase Cnnectivity A.A. 2010/2011 L.Bacci - IS - Capitl 8 2
JDBC: le API Definisce un insieme di Interfacce Java che devn essere implementate dal frnitre dell specific database ttenend i csiddetti driver. Le applicazini usan direttamente le interfacce Java per effettuare le perazini vers il db: viene garantita la prtabilità Le API JDBC sn rganizzate in due package: java.sql package che cntiene DriverManager, Cnnectin, ResultSet, DatabaseMetaData, ResultSetMetaData, PreparedStatement, CallableStatement e Types javax.sql package che cntiene DataSurce A.A. 2010/2011 L.Bacci - IS - Capitl 8 3
JDBC: architettura JDBC supprta sia il mdell a due che a tre livelli Applicazine Java JDBC Applicazine client Applicazine Java ppure brwser HTML Applicazine client Prtcll HTTP, RMI DB Prtcll prprietari DB DB server Applicatin server (Java) JDBC Applicazine server Prtcll prprietari DB DB DB server A.A. 2010/2011 L.Bacci - IS - Capitl 8 4
JDBC: il driver Implementazine delle interfacce JDBC per un specific database Ogni database server ha il su crrispndente driver JDBC Elenc dei driver dispnibili all indirizz: http://develpers.sun.cm/prduct/jdbc/drivers A.A. 2010/2011 L.Bacci - IS - Capitl 8 5
JDBC: tipi di driver Varie implementazini di driver JDBC divisi in categrie: Tip 1 implementa le API JDBC cme una mappatura ad altre API di acces, cme ODBC. Quest tip di driver di slit dipende da librerie native che ne limitan la prtabilità. Il bridge JDBC- ODBC è un esempi di quest tip. Tip 2 scritt parte in Java e parte in cdice nativ. Usa librerie native specifiche del DB a cui si deve cnnettere. Anche in quest cas si ha limitazine della prtabilità. Tip 3 scritt in Java cme un client che si cnnette ad un server middleware usand un prtcll indipendente dal DB. Il server middleware cmunica pi cn il DB usand il prtcll specific del DB. Tip 4 scritt in Java e implementa il prtcll per l access di rete all specific DB. Il client si può cnnettere direttamente al DB. A.A. 2010/2011 L.Bacci - IS - Capitl 8 6
JDBC: l URL del Data Base Serve per effettuare la cnnessine al database Cntiene infrmazini su server, prta, prtcll etc jdbc:subprtcl_name:driver_dependant_dbname Esempi: Oracle (thin driver) jdbc:racle:thin:@lcalhst:1521:sample Derby jdbc:derby://lcalhst:1527/sample Mysql jdbc:mysql://lcalhst:3306/sample A.A. 2010/2011 L.Bacci - IS - Capitl 8 7
Usare JDBC 1. Caricare il driver specific per il DB 2. Ottenere un ggett di tip Cnnectin 3. Ottenere un ggett di tip Statement 4. Eseguire la query 5. Leggere i risultati 6. Leggere i metadati (se necessari) 7. Chiudere gli ggetti Statement e Cnnectin A.A. 2010/2011 L.Bacci - IS - Capitl 8 8
Caricare il driver Per caricare il driver e registrarl press il DriverManager ccrre caricare la sua classe utilizzand l istruzine: Class.frName(String database-driver-class); Esempi: try { // Carica un istanza del driver di Mysql. // Il driver deve essere nella classpath. Class.frName("rg.gjt.mm.mysql.Driver"); } catch (ClassNtFundExceptin cnfe) { System.ut.println("" + cnfe); } A.A. 2010/2011 L.Bacci - IS - Capitl 8 9
Ottenere la cnnessine La classe DriverManager e respnsabile di selezinare il DB e di creare la cnnessine, passand al metd getcnnectin l URL del DB, utente e passwrd: DriverManager.getCnnectin (String url, String user, String passwrd) Esempi: try { Cnnectin cnnectin = DriverManager.getCnnectin ( jdbc:mysql://lcalhst:3306/sample, user1, pwd1 ); } catch(sqlexceptin sqle) { System.ut.println("" + sqle); } Alternativamente e pssibile usare un ggett DataSurce per ttenere la cnnessine A.A. 2010/2011 L.Bacci - IS - Capitl 8 10
DriverManager e Cnnectin Metdi di java.sql.drivermanager: getcnnectin(string url, String user, String passwrd) thrws SQLExceptin Metdi di java.sql.cnnectin: Statement createstatement() thrws SQLExceptin vid clse() thrws SQLExceptin vid setautcmmit(blean b) thrws SQLExceptin vid cmmit() thrws SQLExceptin vid rllback() thrws SQLExceptin A.A. 2010/2011 L.Bacci - IS - Capitl 8 11
Ottenere l ggett Statement L ggett di tip Statement si ttiene dall ggett di tip Cnnectin: Statement statement = cnnectin.createstatement(); Metdi di java.sql.statement: ResultSet executequery(string sql) int executeupdate(string sql) L stess ggett di tip Statement può essere utilizzat per mlte query anche tra lr scllegate. A.A. 2010/2011 L.Bacci - IS - Capitl 8 12
Eseguire la query SELECT: usare il metd executequery(string query) Esempi: ResultSet rs = statement.executequery("select * frm custmer"); L ggett ResultSet rappresenta il risultat della query in frma tabellare; la tabella può essere vuta ma mai null INSERT/UPDATE/DELETE: usare il metd executeupdate(string query) Esempi: int ireturnvalue = statement.executeupdate("update custmer set name = ROSSI' where custmer_cde = 1234567"); Restituisce il numer di righe mdificate nel DB in seguit all esecuzine del cmand Supprta anche i cmandi DDL (Data definitin Language) cme CREATE, DROP, ALTER A.A. 2010/2011 L.Bacci - IS - Capitl 8 13
Leggere i risultati (1) Si cicla attravers il ResultSet per recuperare i dati Metdi di java.sql.resultset: blean next() xxx getxxx(int clumnnumber) xxx getxxx(string clumnname) vid clse() L iteratre e inizializzat nella psizine che si trva prima della prima riga Occrre chiamare next() una vlta per psizinarsi sulla prima riga A.A. 2010/2011 L.Bacci - IS - Capitl 8 14
Leggere i risultati (2) Esempi: while (rs.next()){ // Sbagliat: la prima clnna ha indice 1 e nn 0 String value0 = rs.getstring(0); } // Crrett! String value1 = rs.getstring(1); int value2 = rs.getint(2); duble value3 = rs.getduble(3); A.A. 2010/2011 L.Bacci - IS - Capitl 8 15
Leggere i risultati (3) Usare gli apprpriati metdi getxxx() quand si leggn i dati dal ResultSet getstring() getint() getduble() getobject() Esiste un apprpriat metd getxxx() per gni tip di dat SQL definit nella classe java.sql.types A.A. 2010/2011 L.Bacci - IS - Capitl 8 16
Leggere i metadati Tramite l ggett ResultSet è pssibile ttenere i metadati (ciè i tipi e le prprietà) delle clnne che cmpngn il ResultSet che si sta leggend. ResultSetMetaData rsmeta = rs.getmetadata(); Tramite l ggett Cnnectin è pssibile ttenere i metadati del database che si sta utilizzand. DatabaseMetaData dbmetadata = cnnectin.getmetadata(); A.A. 2010/2011 L.Bacci - IS - Capitl 8 17
Leggere i metadati: esempi ResultSetMetaData meta = rs.getmetadata(); //Restituisce il numer di clnne int iclumncunt = meta.getclumncunt(); fr (int i =1 ; i <= iclumncunt ; i++){ System.ut.println( Clumn Name: " + meta.getclumnname(i)); System.ut.println( Clumn Type" + meta.getclumntype(i)); System.ut.println("Display Size: " + meta.getclumndisplaysize(i) ); System.ut.println("Precisin: " + meta.getprecisin(i)); System.ut.println( Scale: " + meta.getscale(i) ); } A.A. 2010/2011 L.Bacci - IS - Capitl 8 18
DataSurce Un ggett di tip DataSurce è un fabbricatre (factry) di cnnessini vers il database che rappresenta. L interfaccia javax.sql.datasurce è presente nelle API JDBC L ggett è implementat nel driver (fatt dal frnitre del database) Esistn tre tipi di pssibili implementazini: Implementazine base: prduce ggetti Cnnectin standard (cme quelli che si ttengn da DriverManager) Implementazine cn pl di cnnessini: prduce ggetti Cnnectin che partecipan ad un pl di cnnessini Implementazine cn transazini distribuite: prduce ggetti Cnnectin che pssn essere utilizzati per gestire transazini distribuite e che partecipan ad un pl di cnnessini A.A. 2010/2011 L.Bacci - IS - Capitl 8 19
DataSurce: prprietà Un ggett di tip DataSurce ha prprietà che pssn essere mdificate quand è necessari: URL del database Nme del database Prtcll di rete da utilizzare per cllegarsi al database Queste prprietà sn definite in un file di cnfigurazine del cntainer In Tmcat sn definite nel file server.xml presente nella cartella: <TOMCAT_HOME>/cnf/server.xml Vantaggi: se vgli cambiare il DB a cui cllegarmi mi basta mdificare le prprietà nel file di cnfigurazine senza mdificare il cdice! A.A. 2010/2011 L.Bacci - IS - Capitl 8 20
Pl di cnnessini Creare e pi distruggere una singla cnnessine per gni perazine da effettuare vers il database è un prcess che cnsuma temp e risrse Usand un pl di cnnessini invece si ha un insieme di cnnessini : già create e dispnibili al mment dell utilizz risparmiand sui tempi di creazine e distruzine cndivisibili da i vari clienti; ciascuna cnnessine è riciclabile limitate ma espandibili in numer se necessari (per risparmiare sulle risrse) A.A. 2010/2011 L.Bacci - IS - Capitl 8 21
Le transazini Dp l esecuzine di uistruzine SQL, le mdifiche sn autmaticamente cmmittate nel database Per raggruppare due più istruzini in uunica transazine ccrre disattivare tale autmatism: cnnectin.setautcmmit(false) A quest punt è necessari chiamare : cmmit() per registrare permanentemente i cambiamenti rllback() per ripristinare la situazine precedente A.A. 2010/2011 L.Bacci - IS - Capitl 8 22
Le transazini: esempi Cnnectin cnnectin = DriverManager.getCnnectin(url, username, passwd); cnnectin.setautcmmit(false); try { statement.executeupdate(...); statement.executeupdate(...); cnnectin.cmmit(); } catch (Exceptin e) { try { cnnectin.rllback(); } catch (SQLExceptin sqle) { // reprt prblem } } finally { try { cnnectin.clse(); } catch (SQLExceptin sqle) { } } A.A. 2010/2011 L.Bacci - IS - Capitl 8 23
PreparedStatement Se è necessari eseguire più vlte delle istruzini SQL simili, è cnveniente utilizzare le query parametrizzate (prepared statement) Si crea una query in frma standard che è inviata al database per la cmpilazine prima che sia effettivamente usata. Ogni vlta che la si deve utilizzare basta sstituire i parametri utilizzand gli pprtuni metdi setxxx() Piché PreparedStatement eredita da Statement i metdi execute nn hann parametri executequery() executeupdate() A.A. 2010/2011 L.Bacci - IS - Capitl 8 24
PreparedStatement: esempi Cnnectin cnnectin = DriverManager.getCnnectin(url, user, passwrd); PreparedStatement statement = cnnectin.preparestatement("update emplyees "+ "SET salary =? " + "WHERE id =?"); int[] newsalaries = getsalaries(); int[] emplyeeids = getids(); fr(int i=0; i<emplyeeids.length; i++) { statement.setint(1, newsalaries[i]); statement.setint(2, emplyeeids[i]); statement.executeupdate(); } A.A. 2010/2011 L.Bacci - IS - Capitl 8 25