La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Corso Java : Lezione 5 JDBC API : panoramica JDBC API : uso nel codice.

Presentazioni simili


Presentazione sul tema: "Corso Java : Lezione 5 JDBC API : panoramica JDBC API : uso nel codice."— Transcript della presentazione:

1 Corso Java : Lezione 5 JDBC API : panoramica JDBC API : uso nel codice

2 JDBC API : che cosa è ? La JDBC API è una Java API che permette di accedere a qualsiasi tipo di dato in forma “tabellare”, con particolare attenzione ai dati registrati in un database relazionale. La JDBC API è utile per scrivere programmi java che gestiscono queste tre attività : Connessione ad una sorgente di dati ( ad esempio un database ) Far processare delle query e degli statements di update al database Recuperare e processare i risultati ottenuti dal database in risposta a delle query

3 Esempio Questa porzione di codice : Istanzia un oggetto DriverManager
Connection con = DriverManager.getConnection ( "jdbc:myDriver:wombat","myLogin","myPassword“ ); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (rs.next()) { int x = rs.getInt("a"); String s = rs.getString("b"); float f = rs.getFloat("c"); } Questa porzione di codice : Istanzia un oggetto DriverManager Realizza una connessione ad un database Fà un login Istanzia un oggetto Statement Manda uno statement SQL al database Istanzia un oggetto ResultSet Analizza la risposta del database

4 Componenti JDBC API La API JDBC™ permette l’accesso ai dati ( relazionali ) utilizzando il linguaggio Java™. Usando la API JDBC, le applicazioni possono eseguire statements SQL, recuperare i risultati e propagare le modifiche “indietro” alla sorgente dei dati. La API JDBC può interagire simultaneamente con sorgenti di dati multiple ed eterogenee. La API JDBC è parte della piattaforma Java platform( sia Java™ Standard Edition che Java™ Enterprise Edition). La API JDBC 4.0 è divisa in due packages: java.sql and javax.sql. Entrambi i packages sono inclusi sia in Java SE che in Java EE. JDBC DriverManager La classe DriverManager definisce gli oggetti che possono connettere una applcazione Java ad un driver JDBC. DriverManager è tradizionalmente la classe su cui si appoggia l’architettura JDBC. I pacchetti standard di estensione javax.naming e javax.sql permettono l’utilizzo di un oggetto DataSource registrato all’interno di una Java Naming and Directory Interface™ (JNDI). Si possono usare sia i meccanismi di connessione diretta che indiretta, ma la connessione attraverso un oggetto DataSource è da preferirsi ogni volta che sia possibile JDBC Test Suit La JDBC driver test suite permette di determinare quali driver JDBC la nostra applicazione andrà ad usare. Questi test non sono esaustivi, tuttavia riescono a testare molte delle funzioni offerte dalla API JDBC. JDBC-ODBC Bridge Il brigde software permetter un accesso di tipo JDBC attraverso i drivers ODBC. Notare che bisogna caricare i binari del driver ODBC su ogni macchina client della nostra applicazione : l’uso di questi bridge è consigliabile sono in ambiente corporate ( dove l’aggiornamento delle macchine non è normalmente un problema ) o in una applicazione che hanno una architettura “three tier”.

5 Architettura La api JDBC supporta sia l’architettura 2-tier che la 3-tier 2-tier Nell’architettura 2-tier l’applicazione parla direttamente con il datasource : questo richiede che ci sia un driver JDBC specializzato per il datasource che si accede. I comandi inviati dall’applicazione vengono instradati dal datasource così come le risposte. Il driver può trovarsi in un server diverso a cui il client accede attraverso dei protocolli di rete

6 Architettura La api JDBC supporta sia l’architettura 2-tier che la 3-tier 3-tier Nell’architettura 3-tier i comandi vengono inviati ad un “middle tier server” che si occupa di instradare i comandi al datasource che restituisce i risultati al middle tier che li restituisce al client. Questo tipo di architettura permette di semplificare lo sviluppo delle applicazioni lasciando che la parte di “sicurezza” e di gestione delle connessioni sia gestita dal middle tier

7 Stabilire una connessione
Tipicamente, una applicazione che fà uso della JDB API usa DriverManager : l’applicazione carica direttamente il driver JDBC usando una URL scritta all’interno dell’applicazione, la classe DriverManager tenta di caricare i le classe dei driver che sono referenziate nella proprietò di sistema jdbc.drivers DataSource : l’applicazione usa questa interfaccia per richiedere l’oggetto ad un name service provider . Questo permette all’applicazione di disinteressarsi dei dettagli della connessione ( driver, username, password, settaggi del driver … ) Per poter stabilire una connessione c’è bisogno di compiere due passi : Caricare il driver Stabilire la connessione

8 Stabilire una connessione
Caricare il driver Il caricamento del driver è, fondamentalmente, un’operazione da una riga di codice; la classe che rappresenta il driver viene instanziata e questa viene registrata all’interno della lista dei drivers disponibili nella VM Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); Si richiede esplicitamente al class loader di caricare una classe passandogli il riferimento completo <package>.<class name>

9 Stabilire una connessione
Uso di DriverManager La classe lavora in congiunzione con l’interfaccia Driver : legge l’url, riconosce il “subprotocol” e tenta di trovare un driver, disponibile tra i drivers caricati, adatto a gestire quel protocollo. Una volta caricato il driver, si usa il metodo getConnection per recuperare la connessione al database Connection conn = DriverManager.getConnection(<URL>); L’url è una stringa composta da : protocollo:sotto-protocollo:database-name[lista di proprietà] protocollo : nel nostro caso jdbc sotto-protocollo : è il “nome” con cui viene registrato il driver JDBC nome-database : nome del database a cui connettersi [lista di proprietà] : lista di proprietà della connessione Es : jdbc:derby:COFFEES

10 Stabilire una connessione
Uso di DriverManager Il metodo getConnection supporta anche il passaggio di username e password. String url = "jdbc:derby:Fred"; Connection con = DriverManager.getConnection(url, “utente", “password"); Se l’url viene riconosciuta, la classe DriverManager si occupa di gestire tutti i dettagli della connessione e restituisce una connessione aperta al database da cui è possibile creare statements, stored procedures recuperare dati etc etc.

11 Stabilire una connessione
Uso di DataSource : L’uso della classe DataSource aumenta le capacità di portabilità di una applicazione rendendo possibile l’uso di un nome logico piuttosto che definire I dettagli della connessione InitialContext ic = new InitialContext() ; DataSource ds = ic.lookup("java:comp/env/jdbc/myDB"); Connection con = ds.getConnection(); Oppure, per riflettere le stesse caratteristiche di DriverManager DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource(); ds.setPort(1527); ds.setHost("localhost"); ds.setUser("APP"); ds.setPassword("APP");

12 Recuperare i valori Il risultato di una query SQL è, normalmente, una tabella. L’ API JDBC mette a disposizione una interfaccia , ResultSet, che serve a scorrere e a recuperare i valori ritornati dal database Esistono tre tipi di ResultSet : TYPE_FORWARD_ONLY : il ResultSet non è modificabile e lo si può scorrere solo in avanti, da “prima della prima riga” a “dopo l’ultima riga” . Il contenuto del ResultSet dipende dal modo in cui I dati vengono generati dal database : snapshot al momento della select o valore al momento della fetch TYPE_SCROLL_INSENSITIVE : il ResultSet è scrollabile in avanti e indietro di una posizione rispetto alla riga corrente ed è permesso il posizionamento ad una posizione assoluta TYPE_SCROLL_SENSITIVE : il ResultSet è scrollabile in avanti e indietro di una posizione rispetto alla riga corrente ed è permesso il posizionamento ad una posizione assoluta. In aggiunta, il ResultSet è sensibile al cambiamento dei dati fatti in un altra sessione … ma bisogna rileggere il record

13 Recuperare i valori Esempio Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY ); ResultSet srs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES ");

14 Recuperare i valori I metodi di ResultSet per il posizionamento:
next() – muove il cursore avanti di una riga.Ritorna true se si posiziona su una riga o false se si posiziona dopo l’ultima riga previous() - muove il cursore indietro di una riga.Ritorna true se si posiziona su una riga o false se si posiziona prima della prima riga. first() – posiziona il cursore sulla prima riga. Ritorna true se il cursore è sulla prima riga, false se il ResultSet non contiene righe last() – posiziona il cursore sull’ultima riga. Ritorna true se il cursore è posizionato sull’utlima riga, false se il ResultSet non contiene righe beforeFirst() – posiziona il cursore all’inizio del ResultSet, prima della prima riga.Se il ResultSet è vuoto il metodo non ha effetto. afterLast() - posiziona il cursore alla fine del ResultSet, dopo l’ultima riga.Se il ResultSet è vuoto il metodo non ha effetto. relative(int rows) – muove il cursore di n righe, relativamente alla posizione corrente absolute(int row) – muove il cursore alla row-esima riga.

15 Recuperare i valori Esempi Sia srs un ResultSet con 500 righe
srs.absolute(-4); // posiziona alla riga 497 srs.absolute(4); // posiziona alla riga 4 srs.relative(-3); // posiziona alla riga 1 srs.relative(2); // posiziona alla riga 3 srs.absolute(4); int rowNum = srs.getRow(); // rowNum = 4 srs.relative(-3); int rowNum = srs.getRow(); // rowNum = 1 srs.relative(2); int rowNum = srs.getRow(); // rowNum = 3

16 Recuperare i valori Esistono altri quattro metodi per verificare le posizioni “chiave” di un cursore : isFirst isLast isBeforeFirst isAfterLast Normalmente vengono utilizzati all’interno di loop

17 Recuperare i valori I metodi di ResultSet per la lettura:
L’interfaccia ResultSet dichiara i “getters” ( getInt, getBoolean, getObject … ) Le colonne si leggono : Per nome Per posizione ( comincia da 1 ) Se due colonne o più colonne hanno lo stesso nome viene letto il valore della colonna “più a sinistra” Per una maggiore portabilità, non leggere mai la colonna due volte

18 Recuperare i valori Esempio : Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY ); ResultSet srs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES“ while (srs.next()) { String name = srs.getString("COF_NAME"); float price = srs.getFloat("PRICE"); System.out.println(name + " " + price); }

19 Recuperare i valori Esempio : Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); ResultSet srs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES“ srs.afterLast(); while (srs.previous()) { String name = srs.getString("COF_NAME"); float price = srs.getFloat("PRICE"); System.out.println(name + " " + price); }

20 Recuperare i valori Esempio reale: try {
Vector results = new Vector(); Connection con = DriverManager.getConnection(url, "myLogin", "myPassword"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String s = rs.getString("COF_NAME"); float f = rs.getFloat("PRICE"); String text = s + " " + f; results.addElement(text); } stmt.close(); con.close(); setResults(results); } catch(SQLException ex) { setError("SQLException: " + ex);

21 Aggiornare i valori ResultSet : Aggiorna una riga alla volta
Set + Update Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE ); ResultSet srs = stmt.executeQuery( "select COF_Name from COFFEES where price = 7.99“ srs.next(); srs.updateString("COF_NAME", "Foldgers"); srs.updateRow(); Aggiorna una riga alla volta Il metodo cancelUpdates() cancella tutte le update fatte a partire dall’ultimo updateRow();

22 PreparedStatements Sono oggetti Statement (subclasses) che vengono precompilati dal database ( = + veloci ) Sono molto utili quando vengono parametrizzati ed usati all’interno di un loop Si creano allo stesso modo di Statement: PreparedStatement updateSales = con.prepareStatement( "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?“ ); I valori vengono passati utilizzando I setter appropriati : setXXX(posizione, valore) ; updateSales.setInt(1, 75); updateSales.setString(2, "Colombian"); updateSales.executeUpdate(); Lo statement, compilato, precedente è equivalente a stmt.executeUpdate( "UPDATE COFFEES SET SALES = 75 WHERE COF_NAME LIKE 'Colombian'“

23 PreparedStatements Ma in un loop l’uso di PreparedStatement rende il compito + semplice : PreparedStatement updateSales; String updateString = "update COFFEES " + "set SALES = ? where COF_NAME like ?"; updateSales = con.prepareStatement(updateString); int [] salesForWeek = {175, 150, 60, 155, 90}; String [] coffees = {"Colombian", "French_Roast", "Espresso", "Colombian_Decaf", "French_Roast_Decaf"}; int len = coffees.length; for(int i = 0; i < len; i++) { updateSales.setInt(1, salesForWeek[i]); updateSales.setString(2, coffees[i]); updateSales.executeUpdate(); }

24 Transazioni L’API JDBC supporta le transazioni : Per default c’è l’autocommit : ad ogni update o delete viene fatta la commit Si abilita/disabilita l’autocommit con setAutoCommit(boolean valore) Esistono i metodi commit() e rollback() per chiudere o cancellare una transazione Dalla versione 3 della JDBC API esistono i “savepoints” : All’interno di una transazione posso avere delle “mini” transazioni Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) VALUES (?FIRST?)"); // set savepoint Savepoint svpt1 = conn.setSavepoint("SAVEPOINT_1"); rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) " + "VALUES (?SECOND?)"); ... conn.rollback(svpt1); conn.commit(); Viene inserita una riga, settato un savepoint ( svp1 ) e inserita una riga. La rollback arriva fino a svp1 e la commit chiude la transazione inserendo la riga 1 Quando si rilascia un savepoint, il suo utilizzo lancia una SQLException

25 Stored Procedures L’API JDBC supporta le stored procedures Si può creare una stored procedure usando uno statement SQL . Le stored procedures si usano tramite gli oggetti “CallableStatements” String createProcedure = "create procedure SHOW_SUPPLIERS as " + "select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME " + "from SUPPLIERS, COFFEES where SUPPLIERS.SUP_ID = COFFEES.SUP_ID " + "order by SUP_NAME"; Statement stmt = con.createStatement(); stmt.executeUpdate(createProcedure); CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}"); ResultSet rs = cs.executeQuery();


Scaricare ppt "Corso Java : Lezione 5 JDBC API : panoramica JDBC API : uso nel codice."

Presentazioni simili


Annunci Google