Basi Dati Distribuite - A.A. 2004/2005 Introduzione a JDBC Carpini Dania Oliva Giuseppe Petruzzi Marianna Cos’è JDBC (Java Data Base Connectivity) • API sviluppata in Java per scrivere applicazioni indipendenti dal DBMS in uso • Come ODBC implementa lo standard SQL CLI • Versioni – JDBC 1.0 presente a partire da JDK 1.1 – JDBC 2.0 presente a partire da JDK 1.2 • Divisa in due package: Core API (java.sql) Optional Package API (javax.sql) – JDBC 3.0 presente a partire da JDK 1.4 Ogni versione include tutte le funzioni delle precedenti 2 JDBC vs ODBC (1) • ODBC – dipendente dal sistema – utilizzabile da più linguaggi di programmazione – scambio dei dati complesso • JDBC – indipendente dal sistema – utilizzabile solo con il linguaggio JAVA – minore complessità dell’interfaccia • Entrambe le API permettono di richiamare funzionalità specifiche dei DBMS 3 JDBC vs ODBC (2) Indipendenza Indipendenza Indipendenza dal DBMS dal SO dal linguaggio ODBC √ JDBC √ √ √ 4 API JDBC Client 1 Driver 1 DBMS 1 JDBC Driver Manager Driver 2 Client n Driver k API JDBC DBMS m API JDBC Driver 5 Tipi di Driver (1) 1. Driver nativo : • • scritto in codice nativo della macchina su cui si esegue il programma java le richieste JDBC vengono tradotte in richieste a tale driver 2. JDBC/ODBC Bridge : • le richieste JDBC vengono tradotte in richieste ODBC 3. Middleware-server : • le richieste JDBC vengono tradotte in un formato indipendente dal DBMS ed inviate ad uno strumento di middleware (server Java) che le converte in richieste specifiche del DBMS 4. Driver Java : • • scritto interamente in Java non richiede traduzioni intermedie delle richieste 6 Tipi di Driver (2) Tipo 1 JVM Tipo 2 JVM Tipo 3 JVM Tipo 4 JVM Applicazione Java Applicazione Java Applicazione Java Applicazione Java JDBC Driver Manager JDBC Driver Manager JDBC Driver Manager JDBC Driver Manager Traduttore JDBC/Nativo JDBC/ODBC Bridge Middleware server Driver Java Driver Nativo ODBC DBMS DBMS DBMS DBMS 7 Utilizzo di JDBC 1. Caricare il driver JDBC 2. Ottenere una connessione al DataBase • Classi: DriverManager, Connection 3. Interagire con il DBMS inviando comandi e processando gli eventuali risultati • Classi: Statement, ResultSet 4. Chiudere la connessione (è necessario importare le classi del package java.sql) 8 Caricare il driver JDBC • Il Driver Manager mantiene una lista dei driver disponibili nel sistema • È necessario caricare manualmente la classe del driver che si vuole utilizzare, per far sì che venga ″registrata″ in tale lista • Il modo consueto per fare ciò in Java è utilizzare il metodo static forName della classe Class: Class.forName(DriverClassName); 9 Ottenere una connessione al DB • Per stabilire una connessione si richiama il metodo static getConnection della classe DriverManager • Tale metodo restituisce un oggetto di tipo Connection, che rappresenta un canale di comunicazione con il Data Base Connection conn = DriverManager.getConnection( URL, UserName, Password); • È consigliabile chiudere sempre esplicitamente la connessione, per rilasciare le risorse occupate conn.close(); 10 Sintassi dell’URL JDBC • Il formato generale dell’URL è jdbc:<subprotocol>:<subname> – <subprotocol> è il nome del driver o del meccanismo di connettività al DBMS – <subname> è l’identificatore del database (la sintassi varia a seconda del driver) Esempi: jdbc:odbc:clienti jdbc:mysql://localhost/clienti 11 Statement (1) • Per poter inviare comandi al DB è necessario creare un oggetto Statement dalla connessione corrente: Statement stmt = conn.createStatement(); • I principali metodi della classe Statement sono: – executeUpdate(String comandoSQL) • utilizzato per comandi DDL e DML di inserimento, cancellazione o modifica • per i comandi DML restituisce un intero che corrisponde al numero di linee influenzate dall’operazione; per i comandi DDL il valore restituito è sempre 0 – executeQuery(String comandoSQL) • utilizzato per eseguire le interrogazioni (Select) • restituisce un oggetto di tipo ResultSet 12 Statement (2) stmt.executeUpdate(″CREATE TABLE personale (″ ″id INT NOT NULL PRIMARY KEY, ″ ″nome CHAR(20) NOT NULL, ″ ″cognome CHAR(20) NOT NULL, ″ ″qualifica CHAR(30) NOT NULL)″); + + + + stmt.executeUpdate(″ INSERT INTO personale VALUES ″ + ″(1,’Mario’,’Rossi’,’programmatore’)″ ); ResultSet rs = stmt.executeQuery( ″SELECT nome, cognome ″ + ″FROM personale ″ + ″WHERE cognome=’Rossi’″); (Non è necessario inserire il carattere terminatore per i comandi SQL, poiché viene aggiunto dal driver) 13 ResultSet (1) • È un oggetto che permette di recuperare le informazioni ottenute con una query • Il risultato della query è un insieme di righe, che vengono scandite nello stesso ordine in cui sono restituite dal DBMS • Al ResultSet è associato un puntatore (cursore) alla riga corrente – il metodo next() permette di avanzare alla riga successiva • restituisce true se questa è presente • restituisce false se le righe sono terminate – con i metodi getXXX() si recuperano i valori dei singoli campi presenti nella riga corrente 14 ResultSet (2) next() cursore 0 nome (1) cognome (2) 1 Claudio Rossi 2 Mario Rossi 3 Giulia Rossi String Rnome, Rcognome; while (rs.next()) { Rnome = rs.getString(“nome”); Rcognome = rs.getString(2); System.out.println(Rnome + ” “ + Rcognome) } 15 Conversione tipi SQL-JAVA INTEGER REAL CHAR VARCHAR getInt X X X X getFloat X X X X getString X X X X X X X X getDate DATE X getClob getObject CLOB X X X X X X 16 Schema di riepilogo Applicazione Java Connection DBMS Connection Connection DBMS Statement Statement ResultSet ResultSet DATI Si può avere al più un ResultSet per ogni Statement 17 Altri tipi di ResultSet • È possibile creare dei ResultSet con maggiori funzionalità, passando degli opportuni parametri al momento della creazione dello Statement : – scrollable ResultSet : • le righe del risultato possono essere scandite in entrambe le direzioni • ci si può posizionare in maniera “assoluta” su una particolare riga – updatable ResultSet : • mettono a disposizione dei metodi updateXXX analoghi ai metodi getXXX, che consentono di modificare il valore di un campo sulla riga corrente • l’aggiornamento si riflette sulla corrispondente tabella nel database automaticamente 18 Eccezioni e Metadati • La maggior parte dei metodi delle classi finora viste può sollevare delle eccezioni di tipo SQLException • Per avere informazioni sul database si può richiedere un oggetto DataBaseMetaData – si hanno a disposizione metodi per ottenere il nome del db, il numero massimo di connessioni, il nome del driver, ecc. DataBaseMetaData dbmd = conn.getMetaData(); • Per avere informazioni su un ResultSet si può richiedere un oggetto ResultSetMetaData – si hanno a disposizione metodi per ottenere il numero di colonne restituite, i loro nomi e tipi, ecc. ResultSetMetaData rsmd = rs.getMetaData(); 19 Transazioni (1) • La connessione al database per default è in modalità autocommit – Il commit viene automaticamente effettuato al completamento del comando SQL – un comando si considera completato quando: • sono state recuperate tutte le righe nel caso di una SELECT • subito dopo l’esecuzione in tutti gli altri casi (INSERT,...) • Per gestire manualmente il commit dei comandi si deve disabilitare l’autocommit sull’oggetto Connection con il metodo conn.setAutoCommit(false); 20 Transazioni (2) • Una volta disabilitato l’autocommit è necessario invocare esplicitamente i metodi – commit, per rendere permanenti le operazioni effettuate conn.commit(); – rollback, per annullare le operazioni effettuate a partire dall’ultimo commit o rollback conn.rollback(); 21 Transazioni (3) • È possibile impostare dei checkpoint durante una transazione – mediante la creazione di oggetti SavePoint – un’operazione di rollback può disfare tutte le modifiche effettuate a partire da un checkpoint • In JDBC esistono 5 diversi livelli di isolamento per le transazioni (sono i livelli previsti dall’SQL) – permettono di definire il grado di concorrenza delle transazioni – uno dei 5 livelli è scelto di default dal driver JDBC – è consentito modificare tale livello con il metodo della classe Connection setTransactionIsolation(int level); 22 JDBC Optional Package • Le classi sono incluse nel pacchetto javax.sql • Aggiunge ulteriori funzionalità alla API JDBC – l’interfaccia DataSource, come modo alternativo al DriverManager per ottenere connessioni ai database – Pool di connessioni: un meccanismo per il riutilizzo di connessioni esistenti, al fine di ottimizzare i costi di creazione di nuove connessioni – Transazioni distribuite • coinvolgono più DBMS • il loro utilizzo risulta trasparente all’utente, il quale crea e usa le diverse connessioni, lasciandone la gestione al Transaction Manager • l’autocommit è disabilitato e non è consentito invocare i metodi commit e rollback 23 Riferimenti 1. Atzeni, Ceri, Paraboschi, Torlone “Basi di dati”, seconda edizione, McGraw-Hill 1999 2. JDBC 2.0 Fundamentals http://java.sun.com/developer/onlineTraining/Database/JDBC20Intro/JDBC20.html 3. The JDBC 2.0 Optional Package http://java.sun.com/products/jdbc/articles/package2.html 4. Java 2 SDK SE Documentation (ver. 1.4.2) 5. MySQL Connector/J Documentation http://dev.mysql.com/doc/connector/j/en/index.html 24