Documente Academic
Documente Profesional
Documente Cultură
Tipuri de drivere:
Nivel 1: Jdbc-Odbc – utilizează puntea Jdbc-Odbc prin mecanismul
ODBC de conectare la o bază de date
Nivel 2: nativ Java API – combină cod nativ cu cod Java pentru
convertirea cererilor JDBC în comenzi proprietar BD
Nivel 3: Database Midleware – drivere pure Java care folosesc un
server middleware pentru conversia cererilor JDBC in comenzi
DBMS. Serverul lucrează cu diverse tipuri de baze de date. Nu mai
există cod nativ pe partea de client
Nivel 4: Pure Java Driver – conectare directă la BD prin cod Java
utilizând un protocol specific bazei de date
Aplicatie Java Aplicatie Java Aplicatie Java Aplicatie Java
Cod nativ
DBMS
DBMS
Accesarea unei baze de date utilizând JDBC
Testarea cursorului:
int getHoldability() throws SQLException; // rezultatul este unul din cei doi
parametri
Gruparea comenzilor - Tranzacții
Niveluri de izolare:
static final int TRANSACTION_NONE; // nu sunt permise tranzacțiile
static final int TRANSACTION_READ_UNCOMMITTED; // fără izolare
static final int TRANSACTION_READ_COMMITTED; // Este legat de
paradigma citirilor improprii - Dirty Reads. Nivelul trebuie sa înlăture aceste
situații. Soluție: nu sunt citite date care au fost modificate si nu s-au definitivat
modificările prin commit()
static final int TRANSACTION_REPEATABLE_READ; // Este legat de
paradigma “citirilor nerepetabile” - Non-Repeatable Reads. Comenzi
identice de citire dau rezultate diferite in cadrul aceleiași tranzacții.
Soluție: interzice unei tranzacții sa citească din nou date dintr-un rând care
a fost modificat definitiv prin commit() de către o alta tranzacție.
static final int TRANSACTION_SERIALIZABLE; // Elimină și riscurile
create de problema “fantomei” - Phantom Reads. Problema fantomei apare
când o tranzacție inserează/șterge înregistrări selectabile într-o selecție a
altei tranzacții. Soluție: izolarea completa - tranzacțiile sunt serializate.
Exemple
Presupunem că avem o tabelă studenti cu câmpurile nume și media
nume media
Ionescu Dan 9
Popescu Maria 9.33
Dirty Reads
Tranzacția A
UPDATE studenti SET media = 9.5 WHERE nume='Ionescu Dan'
Tranzacția B
SELECT * FROM studenti
Tranzacția A
rollback
Tranzacția A
SELECT * FROM studenti WHERE nume = 'Popescu Maria'
Tranzacția B
UPDATE studenti SET media = 8.50 WHERE nume = 'Popescu Maria'
commit
Tranzacția A
SELECT * FROM studenti WHERE nume = 'Popescu Maria'
commit
Tranzacția A
SELECT * FROM studenti WHERE media > 7
Tranzacția B
INSERT INTO studenti VALUES ('Popa Leon', 7.5)
commit
Tranzacția A
SELECT * FROM studenti WHERE media > 7
commit
Tranzacția B inserează un rând care satisface criteriile de interogare din A dar care nu
apare decât la a doua interogare. Acesta se numește "rând fantomă".
Comenzi precompilate
Într-o aplicație JDBC se lucrează cu trei tipuri de date: tipurile Java, tipurile JDBC,
tipurile SQL (in dialectul corespunzător).
Tipurile JDBC sunt descrise in clasa java.sql.Types sub forma de câmpuri statice int -
BOOLEAN, DATE, DOUBLE etc.
Corespondenta dintre tipuri se face voluntar prin codul aplicației cunoscând
semnificația tipurilor
Prin metoda de instanță a clasei ResultSetMetaData:
int getColumnType(int column) throws SQLException;
se poate obține un tip din Types corespunzător coloanei investigate.
Tipul dată:
public class java.sql.Date extends java.util.Date; // clasa destinată să modeleze data
calendaristica in aplicațiile JDBC
public static Date valueOf(String s); // convertește un String de forma "yyyy-[M]M-[d]d"
in data JDBC
public String toString(); // convertește o data într-un sir in format "yyyy-[M]M-[d]d"
Operațiuni CRUD (Create Read Update Delete) pe ResultSet
Inserare de noi rânduri
Trecerea pe rândul de insert
r.moveToInsertRow();
Operațiuni de inițializare câmpuri
r.updateTip(nrColoana, valoare);
…
Adăugarea rândului
r.insertRow();
Actualizare
r.absolute(i); // trecere pe rândul i
r.updateTip(nrColoana, valoare); // actualizare pe coloana nrColoana
…
r.updateRow(); // inserarea noilor valori
Ștergere
r.absolute(i); // trecere pe rândul dorit
r.deleteRow(); // ștergere
Accesul la metadate
Accesul la metadate prin obiecte Connection - sunt furnizate informații despre baza de
date (structura, tabele/viziuni, catalog etc.)
String getCatalog() throws SQLException; //Întoarce numele de catalog
void setCatalog(String catalog) throws SQLException
DatabaseMetaData getMetaData() throws SQLException; //Întoarce obiect cu
informații de tip metadată la nivelul bazei de date
Furnizarea numelor de tabele și viziuni se face prin metoda getTables a clasei
DatabaseMetaData:
ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern,
String[] types) throws SQLException; // Numele de catalog și de schemă pot fi null.
tableNamePattern este numele tabelei sau o parte din nume, types este un vector de
șiruri care pot fi: "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL
TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM"
Metoda întoarce un obiect ResultSet cu informații privind obiectele interogate (tabele,
viziuni etc). Coloanele obiectului ResultSet cuprind numele de catalog, schema, numele
obiectului (nume de tabelă, viziune etc.), tipul obiectului (tabelă, viziune etc.) etc.
Numele de obiect este coloana 3 sau coloana cu numele "TABLE_NAME".
Accesul la metadate prin obiecte ResultSet - sunt furnizate informații despre setul
interogat (coloane, tipuri, dimensiuni câmp etc.). Informațiile sunt memorate prin
obiecte din clasa ResultSetMetaData. Un obiect ResultSetMetaData se obține prin
metoda getMetaData a interfeței ResultSet:
ResultSetMetaData getMetaData() throws SQLException;
Accesul la informații se face prin metodele ResultSetMetaData:
int getColumnCount() throws SQLException
String getColumnName(int column) throws SQLException
int getColumnType(int column) throws SQLException
String getColumnTypeName(int column) throws SQLException
int getColumnDisplaySize(int column) throws SQLException