interfacce per dbms - unige.it...3 5 jdbc (java data base connectivity) zjdbc (che non è solo un...
TRANSCRIPT
1
1
Interfacce DBMS – in breve
Corso di BD1Ripasso comandi applicazione JDBC Manipolazione estensioni OR in JDBC
2
Interfacce per DBMS
Problema: Far accedere un’applicazione ad una base di datiSoluzione: Librerie di funzioni (SQL/CLI)Chi crea queste librerie?– Caso 1: Librerie proprietarie del DBMS,
applicazione dipendente dal DBMS (es. Oracle Call Interface OCI)
– Caso 2: Librerie standard, applicazioneindipendente dal DBMS
2
3
Interfacce per DBMS
Sono state quindi definite interfacce standard:– ODBC (Open DataBase Connectivity ): scritta in C– JDBC (Java Data Base Connectivity): scritta in
Javale operazioni supportate sono sostanzialmentele stesse, anche se in JDBC la sintassi è piùsemplice
4
Architettura di riferimento
3
5
JDBC (Java Data Base Connectivity)
JDBC (che non è solo un acronimo ma un trademark della SUN) è stato sviluppato nel 1996 dalla Sun Rappresenta una API standard per interagirecon basi di dati da un programma Java (grazie a Java c’è indipendenza dalla piattaforma)Operazioni possibili:– Connessione ad DBMS– Creazione ed invio di statement SQL– Ricezione e manipolazione del risultato
6
API JDBC
JDBC API
Java Applications
JDBC Driver Manager
JDBC Driver JDBC Driver
DBMS DBMS
API
API
4
7
JDBC – Driver Manager
Livello di gestione
Gestisce i driver disponibili, scegliendo quellopiu’ appropriato
8
Realizzano la connessione col DBMSEsistono quattro tipi di driver:1. JDBC-ODBC Bridge + ODBC Driver2. A native-API partly Java technology-enabled driver3. Pure Java Driver for
Database Middleware4. Direct-to-Database
Pure Java Driver.
JDBC - Driver
-portabili
-scritti java
5
9
JDBC – Architettura generale
Java Application
JDBC Driver Manager
JDBC/API nativa(2)
JDBC/ODBC bridge (1)
JDBC/Middleware(3)
JDBC/ java driver(4)
Native driverODBC Driver
DBMS
DB Middleware
client
server
10
JDBC - Tipi di dato
JDBC definisce un insieme di tipi SQL, chevengono poi mappati in tipi Java
Gli identificatori sono definiti nella classejava.sql.Types
6
11
JDBC - Tipi di datoJD B C T ypes M ap ped to Java Types
JD B C Type Java TypeC H AR S tringV AR C H AR S tringLO NG V AR CH AR S tringN U M E R IC java .math .B igDecim alD E C IM AL java .math .B igDecim alB IT boo leanT IN Y INT byteS M ALLIN T shortINT E G E R in tB IG IN T longR E AL f loa tFLO AT doub leD OU B LE doub leB IN AR Y byte []V AR B IN AR Y byte []LO NG V AR BIN AR Y byte []D ATE java .sq l.DateT IM E java .sq l.T im eT IM E S TAM P java .sq l.T im estam p
12
JDBC - Flusso applicativo
Passo 1: Caricamento driver JDBCPasso 2: Connessione DBMSPasso 3: Creazione ed esecuzione statementPasso 4: Elaborazione risultatoPasso 5: Disconnessione
La gestione delle eccezioni è necessaria(SQLException)
7
13
JDBC - Connessione
Per realizzare la connessione vengonoutilizzate le seguenti classi ed interfacce:– interfaccia java.sql.Driver
– classe java.sql.DriverManager
– interfaccia java.sql.Connection
14
JDBC-Passo 1: Caricamentodriver
interfaccia java.sql.Driver: – Non viene esplicitamente utilizzata a livello
applicativo
– Per registrare driver utilizzati nella connessione
8
15
JDBC - Passo 1: Caricamento driver
import java.sql.*; //import package
class JdbcTest{
public static void main (String args []) { Class.forName ("oracle.jdbc.OracleDriver");
//caricamento del driver che si intende utilizzare}
}
16
JDBC - Passo 2: Connessione
classe java.sql.DriverManager– Insieme all’interfaccia java.sql.Driver gestisce i
driver disponibili– Quando viene istanziato un oggetto Driver viene
automaticamente registrato nella classeDriverManager
– Effettua la connessione al DBMS
9
17
JDBC - Passo 2: Connessione
interfaccia java.sql.Connection: – Rappresenta una connessione attiva la DBMS
– permette di inviare una serie di richieste SQL al DBMS
18
JDBC - Passo 2: Connessione
È possibile connettersi a qualunque database, locale e remoto, specificandone l’URLIn JDBC, l’URL è formato da tre parti:jdbc: <subprotocol>: <subname>
– <subprotocol> identifica il driver o il meccanismo diconnessione al database (dipende dal DBMS)
– <subname> dipende da subprotocol ed identifica lo specifico database (dipende dal DBMS)
10
19
JDBC - Passo 2: Connessione-Esempi
jdbc:oracle:thin:@everest:1521:GEN: – subprotocol: Oracle– subname:
thin specifica che deve essere utilizzato Oracle ODBC Thin driverEverest specifica il nome della macchina1521: numero portaGEN: nome database Oracle
jdbc:mysql://cannings.org:3306/test– subprotocol: MySQL– subname:
cannings.org specifica il nome della macchina3306 : numero portatest : nome database MySQL
se si usa JDBC-ODBC driver: jdbc:odbc:subname
20
JDBC - Passo 2: Connessione
La connessione avviene chiamando il metodogetConnection() della classe DriverManager, cherestituisce un oggetto di tipo Connection
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@lumpy:1521:DBname", “myLogin", “myPWD");
Se uno dei driver caricati riconosce l’URL fornito dalmetodo, il driver stabilisce la connessione
11
21
JDBC - Passo 2: Connessione…Class JdbcTest{ Public static void main (String args []) {
Class.forName ("oracle.jdbc.OracleDriver");Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:15
21:dylan", "scott", "tiger");
}}
22
JDBC - Passo 3: Creazione statement
Tipi statement:– Statement non preparati: il piano di accesso viene
generato immediatamente prima dell’esecuzione, query semplici SENZA parametri;
– Statement preparati: la generazione del piano diaccesso e l’esecuzione sono due fasi distinte
Il piano può essere generato una sola volta ed eseguito più volteUtile quando la stessa operazione deve essereeseguita con parametri diversi
12
23
JDBC - Passo 3: Creazione statement non preparati
Un oggetto di tipo Statement viene creato a partire da un oggetto di tipo Connection e permette di inviare comandiSQL al DBMS:Connection con;…Statement stmt = con.createStatement(); //e’ overloaded
Si noti che l’oggetto statement non è ancora associatoall’istruzione SQL da eseguire
– Tale istruzione verrà specificata al momento dell’esecuzione
Uno stesso oggetto Connection puo’ creare piu’ oggettiStatement
24
JDBC - Passo 3: Creazione statement preparati
Un oggetto di tipo PreparedStatement viene creato a partire da un oggetto di tipo Connection e permette diinviare comandi SQL al DBMS:
PreparedStatement queryImp = con.prepareStatement(”SELECT * FROM IMPIEGATI");
La creazione di uno statement preparato richiede la specifica dello statement che dovrà poi essereeseguito
13
25
JDBC - Passo 3: Esecuzionestatement non preparati
Esistono 3 metodi diversi in base al tipo dellostatement SQL query:
– Query SQL (SELECT): (StatementObj).executeQuery(query) RISULTATO: Oggetto ResultSet
– Statement di modifica (DML o DDL):(StatementObj).executeUpdate(query)RISULTATO: Numero righe modificate (0 in caso di statement DDL)
– Statement SQL (non conosciuto a priori) :(StatementObj).execute(query)RISULTATO: true o false
26
JDBC - Passo 3: Esecuzione statement non preparati
Per eseguire una query:stmt.executeQuery(”SELECT * FROM IMPIEGATI");
Per eseguire una operazione di aggiornamento (DML), inclusi gli statement DDL:
stmt.executeUpdate(”INSERT INTO IMPIEGATI VALUES (‘AB34’,‘Gianni’, ‘Rossi’,’GT67’,1500)");
stmt.executeUpdate("CREATE TABLE PROVA (CAMPO1 NUMBER)”);
14
27
JDBC - Passo 3: Esecuzionestatement preparati
Esistono 3 metodi diversi in base al tipo dello statement SQL:
– Query SQL (SELECT): (StatementObj).executeQuery() RISULTATO: Oggetto ResultSet
– Statement di modifica (DML o DDL):(StatementObj).executeUpdate()RISULTATO: Numero righe modificate (0 in caso di statement DDL)
– Statement SQL (non conosciuto a priori):(StatementObj).execute()RISULTATO: true o false
28
JDBC - Passo 3: Uso parametri in statement preparati
Utilizzando PreparedStatement posso passareparametri ad una query I parametri sono identificati da ‘?’I parametri vengono settati mediante:
(StatementObj).setXXX(n, value)Dove :
-XXX e’ un tipo Java (String, Byte, Short, …)-n e’ il numero del parametro “?” da settare-value e’ il valore del parametro
15
29
JDBC - Passo 3: Uso parametri in statement preparati
Esempio:PreparedStatement queryImp = con.prepareStatement(”SELECT * FROM IMPIEGATI WHERE Nome = ? And
Cognome=?");I parametri possono poi essere associati allo statement preparato quando diventano noti.
queryImp.setString(1, ‘Paolo’); // il primo parametro (1) identifica il ? che si vuole considerare
queryImp.setString(2, ‘Rossi’);queryImp.executeQuery(): //esegue lo statement
30
JDBC - Passo 3: Esecuzione statement
Il terminatore dello statement (es. ‘;’) vieneinserito direttamente dal driver prima disottomettere lo statement al DBMS per l’esecuzioneMetodo (StatementObj).close() fine processamentodello statement e rilascio delle risorse
16
31
JDBC - Passo 4: Elaborazionerisultato
Utilizzo un oggetto ResultSet per ritornare e manipolare il risultato di una query, cioe’tabella (soprattutto oggetti Statement)Esempio:
String query = " SELECT * FROM IMPIEGATI ";Statement stmt= conn.createStatement();ResultSet rs = stmt.executeQuery(query);
32
JDBC - Passo 4: Elaborazione risultato
Un oggetto ResultSet mantiene il cursore sulla rigacorrente (inizialmente e’ la prima)
Il metodo next() permette di spostarsi nel result set (cursore):
while (rs.next()) //ritorna true,false{/* get current row */}
lI valore di ritorno e’ false quando non ci sono piùtuple da analizzare
Esistono altri metodi per muovere il cursore (previous(), first(),…)
17
33
JDBC - Passo 4: Elaborazione risultato
Accesso agli attributi con: – A) (ResultsetObj).getXXX(column-name)– B) (ResultsetObj).getXXX(column-number)Dove:
- XXX è il tipo Java nel quale il valore deve essere convertitoA) String s = rs.getString(”Cognome");B) String s = rs.getString(2);
int n = rs.getInt(5);
Usare getInt() per valori numerici, getString() per char, varchar
34
JDBC - Passo 5: Disconnessione
Per risparmiare risorse, può essere utile chiudere gli oggetti di classe Connection, Statement, ResultSet quando non vengono piùutilizzatimetodo close()la chiusura di un oggetto di tipo Connectionchiude tutti gli Statement associati mentre la chiusura di uno Statement chiude ResultSetassociati
18
35
Utilizzo di funzionalità OR daJDBC
Consideriamo JDBC 3 (ma molte estensionigià presenti in JDBC 2)
JDBC 3 conforme SQL99, tipi collezione: no MULTISET, solo ARRAY
Nuove interfacce per implementare mapping ditipi object relational in tipi Java
36
JDBC - Creazione nuovi tipi
Essendo un comando DDL, si utilizza il metodoexecuteUpdate
String type = "CREATE TYPE t_indirizzo AS OBJECT (" + "via VARCHAR(50),"+"numero_civico INTEGER," +"cap INTEGER," + "città VARCHAR(20),"+"provincia VARCHAR(2),"+"stato VARCHAR(2))";
Statement st = con.createStatement( ); // non prepared statementst.executeUpdate(type);
19
37
JDBC - Manipolazione nuovi tipi
Nuove interfacce standard JDBC (solo per tipi standard):– STRUCT
per mappare ADT
– REFper mappare valori di tipo riferimento
– ARRAYper mappare valori di tipo array
– SQLDATAper semplificare mapping di ADT
38
Per ogni interfaccia, il driver JDBC relativo ad un particolare DBMS, specificherà una classeche implementa l’interfaccia
Questo permette di gestire le eventualidifferenze esistenti tra DBMS
JDBC - Manipolazione valori nuovitipi
20
39
JDBC - Tipi semplici
Non è introdotta nuova interfacciaSi manipolano utilizzando i metodi del tipo dibaseEsempio
– CREATE TYPE id_impiegato AS INTEGER FINAL;
– Si usano i metodi getInt() e setInt() per leggere e scrivere campi di tipo id_impiegato
40
JDBC - ADT
Le istanze di tipi ADT vengono mappate in istanze diclasse StructUn oggetto di tipo Struct contiene un valore per ogniattributo dell’ADT a cui si riferisceI metodi per poter leggere e scrivere valori di attributicon tipo ADT sono
– ResultSet - getObject(int): per accedere istanza ADT– Struct - getAttributes(): per accedere le componenti di
un’istanza (attributi)– PreparedStatement - setObject(int, Struct): per settare
parametri di tipo ADT
21
41
JDBC - ADT - Esempio
type="CREATE TABLE Impiegati ("+"imp# INTEGER,"+"nome VARCHAR(20),"+"cognome VARCHAR(20),"+ "indirizzo t_indirizzo)";
vogliamo attribuire all’impiegato con nome= “Gianni”cognome= “Verdi” lo stesso indirizzo dell’impiegato cheha imp#=12
42
Esempio (continua)String query = “select indirizzo from Impiegati where imp# = 12”;Statement st = con.createStatement();ResultSet rs = st.executeQuery(query);rs.next();
Struct indirizzo = (Struct) rs.getObject(1); //si ottiene l’istanzaObject[ ] ind_attr = indirizzo.getAttributes(); //si accedono gli attributiSystem.out.print( “Via ” + ind_attr[0] + “ “ + ind_attr[1] + “ “ + ind_attr[2]
+ “ “ + ind_attr[4] + “ “ + ind_attr[3]);
22
43
Esempio (continua)String up = “update Impiegati set indirizzo = ? where nome =‘Verdi’”;PreparedStatement pst = con.prepareStatement(up);pst.setObject(1, indirizzo);pst.executeUpdate( );
44
Tipi riferimento
Le istanze di tipi riferimento (puntatori) vengonomappate in istanze di classe Refi metodi per poter leggere e scrivere valori di attributi con tipo riferimento sono
– ResultSet - getRef(int): per accedere attributi di tipo riferimento– Ref - getObject( ): dato un valore di tipo riferimento, restituisce
l’oggetto puntato (solo JDBC 3)– Ref - setObject(Struct): il parametro diventa il nuovo oggetto
puntato (solo JDBC 3)– PreparedStatement - setRef(int, Ref): per settare parametri di
tipo riferimento
23
45
Tipi riferimento - EsempioCREATE TYPE t_progetto AS
prj# INTEGER,nome VARCHAR(20),descrizione VARCHAR(50),budget INTEGER;
CREATE TABLE Progetti of t_progetto;
CREATE TABLE Impiegati(imp# INTEGER PRIMARY KEY,nome VARCHAR(50),indirizzo t_indirizzo,assegnamento REF(t_progetto));
46
Tipi riferimento - Esempio(continua)
Si vuole associare il progetto dell’impiegato 12 a Verdi e visualizzare le informazioni su tale progetto
24
47
Tipi riferimento - Esempio(continua)String query = “select assegnamento from Impiegati where imp# =
12”;
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query);
rs.next();
48
Tipi riferimento - Esempio(continua)Ref assegn_ref = rs.getRef(1); //si ottiene
l’identificatoreString update = ‘”update impiegati set assegnamento = ?
where nome = “Verdi”;PreparedStatement pst = con.prepareStatement(update);pst.setRef(1,assegn_ref);pst.executeUpdate( );
Struct progetto = (Struct) assegn_ref.getObject( );Object [ ] prog_attr = progetto. getAttributes();System.out.print(ind_attr[0] + “ “ + ind_attr[1] + “ “ +
ind_attr[2] + “ “ + + ind_attr[3]);
25
49
Tipi arrayLe istanze di tipi SQL Array vengono mappate in istanze diclasse Array I metodi per poter leggere e scrivere valori di attributi di tipoarray sono
– ResultSet - getArray(): per accedere attributi di tipo array (restituisce un puntatore all’istanza)
– Array - getArray( ): permette di copiare i dati contenuti nell’array in strutture locali al programma
– Array - getResultSet (): restituisce un result set che contiene unatupla per ogni elemento dell’array, con due colonne. La prima contiene l’indice (partendo da 1), la seconda il valore
– PreparedStatement - setArray(int,Array): per settare parametri ditipo Array
50
Tipi array - EsempioCREATE TABLE Impiegati(
imp# INTEGER,nome VARCHAR(50),indirizzo t_indirizzo,competenze VARCHAR(20) ARRAY[10]);
si vogliono stampare tutte le competenze dell’impiegato 12
26
51
Tipi array - Esempio (continua)String query = “select competenze from Impiegati where imp# = 12”;Statement st = con.createStatement();ResultSet rs = st.executeQuery(query);rs.next();Array comp = rs.getArray(1); //restituisce un puntatore all’arrayString [ ] comp_arr = (String [ ]) comp.getArray( );for (int i = 0; i < comp_arr.length(); i++)
System.out.print(comp_arr[i])
52
Tipi collezione
Varray tipo arrayil driver potrà eventualmente utilizzare la classe Array anche per gestire altri tipi collezione– in JDBC le nested table di Oracle si mappano in
oggetti di tipo Array
27
53
SQL DataInterfacciaogni classe che implementa SQLData permettedi definire un mapping esplicito tra un tipo SQL e una classe Java– casting definito esplicitamente dall’utente
semplifica l’accesso agli oggetti strutturati– la lettura di un oggetto restituisce un’istanza della
classe associata dal mapping– non si devono piu’ utilizzare Struct e Object
non lo vediamo