Odata cu maturizarea limbajului si aparitia tehnologiilor având la baza Java Development Kit, firma Sun Microsystem ofera pietei noul API - JDBC 2.0, având ca principal scop completarea precedentului sau JDBC 1.0. Astfel, mostenind capabilitati din prima versiune, acesta îsi propune o serie de lucruri noi, tinând oarecum pasul cu platforma Java. Elemente noi ca si Java Transaction Service (JTS), Java Naming and Directory Interface (JNDI), Enterprise Java Beans (EJB), Internationalization fac din Java 2 Enterprise Edition un produs performant. JDBC 2.0 API cunoaste toate aceste elemente, oferindu-le suport si totodata aliniindu-se si el în galeria plina de success a lui J2EE.
Ce aduce în plus JDBC2.0?
Exista câteva caracteristici importante furnizate bazelor de date care nu sunt suportate de JDBC 1.0 API, cum ar fi suport pentru cursoare scrollable si tipuri de date avansate, sau chiar suport pentru tipul de date BLOB (Binary Large Objects) si care sunt suportate de JDBC 2.0.
De asemenea trebuie sa furnizeze un cadru de lucru care sa permita accesarea instantelor de tipuri de date definite de utilizator, stocate în baza de date. API 2.0 suporta ambele tipuri de baze de date atât cele care furnizeaza capabilitati de stocare ale obiectelor Java, cât si baze de date care stocheaza tipuri de date structurate SQL3.
JDBC 2.0, extensia standard, furnizeaza suport de baza limitat, pentru acces la date de tip tabular non-SQL, de exemplu, date stocate într-un fisier.
Îmbunatatiri aduse tipului ResultSet
În principal este vorba despre doua noi caracteristici: cea de scrolling si cea de actualizare (updating). Cele mai importante metode adaugate driver-ului JDBC pentru a reusi îmbunatatiri simtitoare în aceaste directii sunt ilustrate în cele ce urmeaza:
-Scrolling
Result Set, creat prin executia unui Statement, care asigura abilitati de miscare în ambele sensuri ("last -to-first" si "first-to-last") poarta numele de scrollable Result Set. De asemenea mai suporta pozitionare absoluta si relativa. Prima se traduce prin capacitatea de miscare direct la un rând prin specificarea pozitiei lui în Result Set. Pozitionarea relativa pune în evidenta capacitatea de miscare la un rând prin specificarea pozitiei relative cu rândul current.
Trei tipuri de Result Set
Daca API 1.0 ofera un singur tip de Result Set, API 2.0 furnizeaza trei tipuri: "forward-only", cunoscut si de JDBC 1.0, scroll-insensitive, si scroll-sensitive. Asa cum le spune si numele, noile tipuri suporta scrolling, dar difera în vizibitatea schimbarilor facute în timpul în care este utilizata conexiunea la baza de date: primul este în general nesesizabil la schimbari si furnizeaza vizibilitate statica datelor vizate pe care le contine, al doilea însa, sesizeaza schimbarile aparute în timpul în care conexiunea este deschisa, si furnizeaza vizualizare dinamica a datelor.
-Doua tipuri de concurente
Primul tip se numeste "read-only" si nu permite modificarea continutului acelui Result Set. Al doilea-actualizabil, permite modificari si poate fi utilizat pentru rezolvarea accesului la aceleasi date utilizând tranzactii diferite.
Cum se creaza un ResultSet?
În exemplul de mai jos se creaza un Result Set de tip forward-only ce utlilizeaza concurenta de tip read-only. În crearea unui ResultSet este utilizat nivelul predefinit de izolare al tranzactiei.
Connection con = DriverManager.getConnection ("jdbc:my_subprotocol:my_subname"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT emp_no, salary FROM employees"); |
Exemplul urmator creaza un Result Set scrollabil, modificabil si sensibil la modificari. Se extrag din baza de date 25 de rânduri la un moment de timp.
Connection con = DriverManager.getConnection("jdbc:my_subprotocol:my_subname"); Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE ); stmt.setFetchSize(25); ResultSet rs = stmt.executeQuery("SELECT emp_no, salary FROM employees"); |
În exemplul urmator se creaza un Result Set cu aceleasi atribute ca si cel precedent, utilizând însa un obiect de tip PreparedStatement pentru a-l produce.
PreparedStatement pstmt = con.prepareStatement("SELECT emp_no, salary FROM employees where emp_no = ?",ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); pstmt.setFetchSize(25); pstmt.setString(1, "100010"); ResultSet rs = pstmt.executeQuery(); |
Metoda supportsResultSetType() din clasa
DatabaseMetaData poate fi apelata pentru a vedea ce tipuri ResultSetpot sunt sustinute de
driverul JDBC. Cu toate acestea, s-ar putea ca o aplicatie sa
ceara în continuare un driver JDBC
pentru a crea un obiect Statement
, PreparedStatement
, sau CallableStatement folosind un tip
ResultSet caruia driverul nu îi poate oferi suport. În acest caz, driverul
ar trebui sa puna problema unui SQLWarning pe conexiunea care produce
obiectul Statement si sa aleaga o varianta alternativa
pentru tipul Result Set al
obiectului conform urmatoarelor reguli:
Daca o aplicatie cere un tip ResultSet tabelar, atunci driver-ul ar trebui sa foloseasca un tip tabelar caruia îi poate oferi suport, chiar daca acesta difera de tipul exact cerut de aplicatie.
Daca aplicatia cere un tip Result Set tabelar, iar driver-ul nu poate suporta tabelarea, atunci driver-ul ar trebui sa foloseasca un ResultSet de tip forward-only.
În mod
similar, metoda supportsResultSetConcurrency()
a clasei DatabaseMetaData
poate fi apelata pentru a
determina ce tipuri concurenta sunt suportate de catre driver.
Daca o aplicatie cere un driver
JDBC pentru un tip concurenta caruia nu îi poate oferi
suport atunci driver-ul ar trebui sa puna problema unui SQLWarning
pe conexiunea care produce obiectul de tip Statement
si sa aleaga tipul concurenta alternativ. Alegerea
tipului ResultSet ar trebui
facuta daca o aplicatie precizeaza atât un tip ResultSet cât si un tip
concurenta, ambele neputând fi suportate.
În
anumite cazuri, un driver JDBC ar
putea avea nevoie sa aleaga un tip ResultSet alternativ sau unul concurenta pentru un ResultSet
la timpul de executie al obiectului de tip Statement. De exemplu, un obiect Statement SELECT, care contine o legatura cu mai multe
tabele, s-ar putea sa nu aiba ca rezultat un obiect de tip ResultSet ce poate fi adaptat. În acest
caz driver-ul JDBC ar trebui sa puna problema unui SQLWarning asupra obiectului de tip Statement, PreparedStatement sau CallableStatement
care are ca rezultat
ResultSet
-ul,
si sa aleaga un tip ResultSet
corespunzator sau unul concurenta dupa cum a fost
descris mai sus. O aplicatie ar putea determina tipul ResultSet efectiv si cel concurenta ale unui ResultSet apelând metodele getType()
si respectiv getConcurrency()
din clasa
ResultSet
.
Un ResultSet poate fi actualizabil
daca tipul concurentei este CONCUR_UPDATABLE
.
Liniile dintr-un ResultSet asupra
caruia se pot face schimbari pot fi adaptate, inserate sau
sterse. Exemplul de mai jos actualizeaza prima linie a unui ResultSet. Metodele ResultSet.updateXXX()
sunt folosite pentru a adapta valoarea unei coloane
individuale în linia curenta, si nu pentru a actualiza baza de date
în cauza
Când este apelata metoda updateRow()
din clasa ResultSet
baza de date este actualizata. Coloanele pot fi
specificate prin numele sau numarul lor.
rs.first(); rs.updateString(1, "100020"); rs.updateFloat("salary", 10000.0f); rs.updateRow(); |
Actualizarile
pe care le face o aplicatie trebuie sa fie înlaturate de
catre un server JDBC daca aplicatia muta cursorul de la linia curenta înainte de a apela updateRow()
.
În plus, o aplicatie poate apela metoda cancelRowUpdates()
din
clasa ResultSet
pentru a renunta în mod explicit la
actualizarile
facute
asupra liniei
Metoda
cancelRowUpdates()
trebuie
apelata dupa apelarea metodei updateXXX()
si înainte de a apela
metoda updateRow()
în caz
contrar, nu are nici un efect.
Exemplul urmator pune în evidenta stergerea unei linii. Linia a cincea din obiectul de tip ResultSet este stearsa din baza de date.
rs.absolute(5); rs.deleteRow(); |
Exemplul
de urmator descrie modul în care poate fi inserata o noua linie
într-un obiect de tip ResultSet. JDBC
2.0 API defineste conceptul de rând de inserat, asociat fiecarui
obiect de tip ResultSet si
utilizat ca spatiu pentru crearea continutului noului rând înainte ca
el sa fie autoinserat în obiectul de tip ResultSet. Metoda moveToInsertRow()
din
clasa
ResultSet
este utilizata pentru
pozitionarea cursorului obiectului de tip ResultSet pe linia de inserat.
Metodele
updateXXX()
si
getXXX()
din
clasa
ResultSet
sunt utilizate pentru a actualiza sau a
returna valorile individuale din coloanele liniei de inserat. Continutul
acestei linii este nedefinit imediat dupa apelarea
moveToInsertRow()
din
clasa
ResultSet
. Altfel spus, valorile returnate prin
apelarea metodei
getXXX()
sunt nedefinite dupa ce s-a
apelat metoda
moveToInsertRow()
înainte
ca valorile sa fie setate prin apelarea metodei
updateXXX()
Odata ce
toate valorile coloanelor sunt setate în
insert row
, este apelata metoda
insertRow()
pentru a actualiza simultan obiectul de
tip
ResultSet
si baza de date. Daca o
coloana nu are atribuita o valoare prin apelarea metodei
update()
, sau o coloana lipseste din obiectul de tip
ResultSet, aceasta valoare este trecuta implicit cu valoarea null.
Altfel, apelarea metodei
insertRow()
va genera o exceptie de tip
SQLException
rs.moveToInsertRow(); rs.updateString(1, "100050"); rs.updateFloat(2, 1000000.0f); rs.insertRow(); rs.first(); |
Un
obiect de tip ResultSet retine
pozitia curenta a cursorului atâta timp cât cursorul lui este
pozitionat pe insert row. Saltul
de pe insert row se poate realiza
astfel încât orice metoda de pozitionare a cursorului poate fi apelata, inclusiv
metodele speciale moveToCurrentRow()
care returneaza cursorul la
fostul rând curent înainte de apelarea metodei
moveToInsertRow()
. În
exemplul de mai jos este apelata metoda
first()
pentru
a realiza saltul de pe insert row direct pe primul rând al obiectului de tip
ResultSet.
Datorita diferetei dintre
implementarile bazelor de date, JDBC 2.0 API nu specifica o
multime exacta de interogari SQL care trebuie sa realizeze
un obiect de tip ResultSet adaptabil pentru drivere JDBC care suporta
adaptabilitate. Dezvoltatorii de aplicatii au la dispozitie
urmatoarele tipuri de interogari pentru obtinerea obiectelor de
tip
ResultSet
Interogari ce referentiaza un singur tabel în
baza de date
Interogare ce nu contine nici o operatie JOIN
Interogare ce selecteaza primary key al unui tabel.
Interogare ce selecteaza toate coloanele nenule din tabel.
Interogare ce selecteaza toate coloanele care nu au o valoare implicita.
Un obiect de tip ResultSet mentine un pointer intern numit cursor care indica rândul curent accesat din interiorul acestui obiect. Acest cursor este asemeni cursorului întâlnit pe monitorul calculatorului, ce indica pozitia curenta de pe monitor (linia x, coloana y). Cursorul mentinut de un obiect ResultSet de tip forward only nu poate executa decât miscare înainte prin continutul obiectului ResultSet. Deci, rândurile sunt accesate secvential începând cu primul rând. Aceasta se realizeaza prin apelarea metodei next() a interfetei ResultSet asemeni utilizarii lui JDBC 1.0 API.
Obiectele ResultSet scrollabile implementeaza metoda beforeFirst(), care poate fi apelata sa pozitioneze cursorul înaintea primului rând din obiectul ResultSet.
Exemplul de mai jos ilustreaza pozitionarea cursorului înaintea primului rând si trecerea iterativa prin continutul obiectului result set. Metodele getXXX(), metode JDBC 1.0 API, sunt folosite pentru citirea valorilor coloanelor.
rs.beforeFirst(); while ( rs.next()) |
Un result set scrollabil poate executa mutarea cursorului si de la sfârsit spre început ca în exemplul de mai jos:
rs.afterLast(); while (rs.previous()) |
În acest caz, metoda afterLast() pozitioneaza cursorul dupa ultimul rând în result set. Metoda previous() este apelata pentru a muta cursorul de la sfârsit spre început. Aceasta metoda, asemeni metodei next() returneaza FALSE daca nu exista mai multe elemente, sau în cazul în care cursorul trece ultima pozitie vizata. Dupa examinarea atenta a interfetei ResultSet, veti recunoaste fara dubii ca exista mai multe cai de a parcurge iterativ rândurile unui ResultSet scrollabil. Iata un exemplu incorect:
// incorrect!!! while (!rs.isAfterLast()) |
Acest exemplu încearca o parcurgere iterativa prin continutul unui result set scrollabil, fiind însa incorect din câteva motive. Primul, apelarea metodei isAfterLast() din interfata ResultSet când obiectul result set este vid. Un alt motiv îl reprezinta pozitionarea cursorului înaintea primului rând care contine date.
Exemplul de mai jos fixeaza problemele aparute în cel anterior. Apelarea metodei first() este utilizata pentru a distinge daca obiectul ResultSet este sau nu vid. Se face remarcat faptul ca metoda isAfterLast() este apelata doar dupa ce în prealabil, s-a testat daca result set nu este vid. Controlul buclei lucreaza corect, si cu ajutorul metodei relative(1) se parcurge continutul obiectului result set dupa ce s-a facut pozitionarea cursorului pe primul rând.
if (rs.first()) |
Chiar daca ne gandim ca cele mai multe drivere JDBC suporta obiecte result set scrollabile, în practica se ocoleste aceast lucru, care duce la un grad de complexitate mare în implementarea lor pentru surse de date care nu suporta proprietatea de scrolling. Daca DBMS asociat cu un driver nu suporta proprietatea de scrolling, atunci aceasta poate fi omisa, sau un driver poate implementa aceasta proprietate ca si un nivel superior al DBMS. Este important de notat ca JDBC rowset, care este o parte a JDBC standard extension API, suporta scrolling si poate fi utilizat când DBMS nu suporta aceasta proprietate.
Aceasta facilitate permite operatiilor de actualizari multiple sa fie executate pentru procesarea unei singure comenzi. Executarea actualizarilor multiple în locul celor individuale pot îmbunatati vizibil performantele, în diferite situatii. Obiecte de tip Statement, PrepareStatement, si CallableStatement pot fi folosite pentru executarea acestei facilitati.
Utilizarea actualizarilor batch (Use of batch updates)
Statements - proprietatea batch updates permite unui obiect de tip Statement sa execute un set de comenzi heterogene de actualizari, ca o singura unitate, sau comanda. În exemplul de mai jos, toate operatiile de actualizare dorite pentru inserarea unui nou angajat în baza de date a unei companii fictive sunt executate ca o singura comanda.
// turn off autocommit con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe Jones')"); stmt.addBatch("INSERT INTO departments VALUES (260, 'Shoe')"); stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)"); // submit a batch of update commands for execution int[] updateCounts = stmt.executeBatch(); |
Se observa dezactivarea operatiei autocommit, si acest lucru este important când se doreste utilizarea actualizarilor comenzilor.
În JDBC 2.0, un obiect de tip Statement, cunoaste o lista de comenzi care se pot executa împreuna. La crearea unui astfel de obiect, lista asociata lui este vida. Adaugarea unui element în lista se face folosind metoda addBatch(). Numai comenzi DDL si DML, care returneaza un numar de actualizari simple, pot fi executate în interiorul unui batch. Pentru mai multe informatii se recomanda studierea cu atentie a documentatiei atasate pachetului javax.sql.
Prepared Statements - actualizarea comenzii este folosita si pentru asocierea multimilor multiple de valori ale parametrilor de intrare cu un singur obiect de tip PreparedStatement. Exemplul de mai jos insereaza doua noi înregistrari de angajati în baza de date ca o singura comanda. Metodele setXXX() sunt utilizate pntru a creea fiecare o multime de parametrii, una pentru fiecare angajat, iar metoda addBatch() adauga multimea de parametri la comanda curenta.
// turn off autocommit con.setAutoCommit(false); PreparedStatement stmt = con.prepareStatement( "INSERT INTO employees VALUES (?, ?)"); stmt.setInt(1, 2000); stmt.setString(2, "Kelly Kaufmann"); stmt.addBatch(); stmt.setInt(1, 3000); stmt.setString(2, "Bill Barnes"); stmt.addBatch(); // submit the batch for execution int[] updateCounts = stmt.executeBatch(); |
Callable Statements - facilitatea batch update lucreaza asemenea cu obiecte de tip CallableStatement ca si cu obiecte de tip PreparedStatement. Multimi multiple de valori ale parametrilor de intrare pot fi asociate cu un obiect de tip CallableStatement si trimise la DBMS. Procedurile stocate invocate utilizând facilitatea amintita mai sus cu un obiect de tip CallableStatement trebuie sa returneze un numar de actualizari si nu pot avea parametri de intrare sau de iesire. Daca aceasta restrictie este violata metoda executeBatch() va lansa o exceptie.
În API 1.0 am întâlnit suport pentru stocarea si salvarea obiectelor Java dintr - o baza de date utilizând mecanismul format din metodele getObject() si setObject(). API 2.0 intensifica abilitatea driverului JDBC de - a implementa facilitati în lucrul cu obiecte Java, în general, prin furnizarea noilor capacitati metadata care pot fi utilizate în descrierea obiectelor Java pe care sursa de date le contine. Instantele claselor Java pot fi stocate ca si obiecte Java serializate, sau în alte formate specifice furnizorului. Daca este utilizata serializarea obiectelor, atunci, referintele între obiecte pot fi tratate în concordanta cu regulile specifice serializarilor obiectelor Java.
Salvarea obiectelor Java
Exemplul de mai jos descrie modul cum pot fi stocate obiectele Java. Interogarea din exemplu referentiaza tabelul PERSONNEL care contine o coloana numita Emplyee, continând instante de clase Java.
ResultSet rs = stmt.executeQuery( "SELECT Employee FROM PERSONNEL"); rs.next(); Employee emp = (Employee)rs.getObject(1); |
Exemplul selecteaza toate obiectele de tip Emplyee din tabelul PERSONNEL. Metoda next(), cunoscuta din API 1.0, pozitioneaza cursorul în obiectul result set pe prima pozitie, continând obiect Employee. Prin apelarea metodei getObject() se citeste instanta clasei Employee ca si obiect neserializat pe care aplicatia o va face Employee prin cast.
Stocarea obiectelor Java
Exemplul urmator ilustreaza procesul de actualizare a obiectelor Java si realizarea copiilor actualizate ale lor.
emp.setSalary(emp.getSalary() * 1.5); PreparedStatement pstmt = con.preparedStatement( "UPDATE PERSONNEL SET Employee = ? WHERE Employee.no = 1001"); pstmt.setObject(1, emp); pstmt.executeUpdate(); |
Din start se apeleaza metoda getSalary() pentru a actualiza salarul angajatului. De notat ca semantica metodelor care descriu comportamentul clasei Employee nu sunt specifice JDBC. Noi discutam despre aceasta clasa ca si despre una normala si apelam metoda setSalary() doar pentru a schimba valoarea unor câmpuri de date private continute de instanta clasei Employee.
Apoi obiectul PreparedStatement este creat utilizând comanda extinsa UPDATE - sintaxa utilizata este din nou necunoscuta de JDBC. Aceasta comanda specifica faptul ca, coloana Employee a tabelului PERSONNEL este modificabila. Metoda setObject() este utilizata pentru a trece obiectele de tip Employee obiectului prepared statement, iar pe urma se apeleaza metoda executeUpdate() pentru a actualiza valoarea Employee stocata în baza de date.
Salvarea variabilelor BLOB si CLOB
Tipurile de date BLOB si CLOB sunt tratate similar cu celelalte tipuri de date, existente în JDBC. Valorile acestor tipuri de date pot fi salvate prin apelarea metodelor getBlob() si getClob() care apar în interfetele ReslutSet sau CallableStatement. De exemplu,
Blob blob = rs.getBlob(1); Clob clob = rs.getClob(2); |
salveaza valoarea BLOB din prima coloana a obiectului de tip ResultSet si cea CLOB din a doua coloana. Interfata Blob contine metode pentru returnarea lungimii unui BLOB, a numarului de octeti continuti în acel BLOB, etc. Interfata Clob contine operatiile corespunzatoare bazate pe caractere. Pentru mai multe informatii va rugam sa consultati documentatia acestui pachet.
O aplicatie JDBC nu lucreaza direct cu tipuri LOCATOR (blob) si LOCATOR (clob) care sunt definite în SQL. Implicit, driverul JDBC implementeaza interfetele Blob si Clob folosind tipuri de locatori apropiati. De asemenea, implicit, doar obiectele Blob si Clob ramân valide în timpul tranzactiei în care acestea sunt create. Driverul JDBC poate permite schimbarea acestor setari implicite.
Stocarea obiectelor BLOB si CLOB
Valorile obiectelor de tip BLOB si CLOB pot fi folosite ca si parametrii de intrare pentru un obiect de tip PrepareStatement la fel ca în cazul altor tipuri de date JDBC prin apelarea metodelor setBlob() si setClob(). Metodele setBinaryStream() si setObject() pot fi utilizate pentru a facilita lucrul cu obiecte de tip BLOB. Metodele setAsciiStream(), setUnicodeStream(), setObject() pot fi utilizate pentru a facilita lucrul cu obiecte de tip CLOB.
Salvarea tablourilor
Date de tip tablou SQL pot fi salvate apelând metoda getArray() din interfetele ResultSet si CallableStatement. De exemplu,
Array a = rs.getArray(1); |
citeste un tablou din prima coloana a obiectului de tip ResultSet. Implicit, driverul ar putea implementa interfata Array utilizând un SQL LOCATOR(array) intern. De asemenea, obiectele tablou implicite ramân valide numai pe durata tranzactiei în care au fost create. Aceaste setari implicite pot fi schimbate pentru tipurile CLOB si BLOB, dar API 2.0 nu specifica modul de realizare.
Interfata Array furnizeaza câteva metode care returneaza continutul tabloului ca un tablou Java sau obiect ResultSet. Aceastea sunt getArray() si respectiv getResultSet(). Pentru mai multe detalii consultati documentatia atasata acestui pacchet.
Stocarea tablourilor
Metoda setArray() din interfata PreparedStatement poate fi apelata pentru a introduce valorile de tablou ca si parametrii de intrare a unui obiect de tip PreparedStatement. Un tablou Java poate fi introdus ca si parametru de intrare si apelând metoda setObject() din interfata PreparedStatement.
Citirea referintelor
O referinta SQL poate fi salvata prin apelarea metodei getRef() din interfetele ResultSet si CallableStatement. De exemplu,
Ref ref = rs.getRef(1); |
citeste o referinta din prima coloana a obiectului de tip ResultSet. Implicit, citirea unei valori Ref nu materializeaza datele pe care aceasta le refera. De asemenea, implicit o valoare Ref ramâne valida pâna când sesiunea sau conexiunea creata este deschisa. Aceaste setari implicite pot fi suprascrise, dar API 2.0 nu specifica modul de realizare.
Stocarea referintelor
Prin apelarea metodei setRef() din interfata PreparedStatemet se poate introduce o referinta ca si parametru de intrare a unui obiect prepared statement.
Citirea tipurilor distincte
Implicit, o secventa de date ce contine tipul SQL DISTINCT poate fi salvata prin apelarea oricarei metode getXXX() din interfata ResultSet. Sa urmarim urmatoarea declarare de tip de date:
CREATE TYPE MONEY AS NUMERIC(10,2) |
O valoare a tipului MONEY poate fi citita dupa cum urmeaza:
java.math.BigDecimal bd = rs.getBigDecimal(1); |
atâta timp cât tipul de date SQL NUMERIC este mapat la tipul de date java.math.BigDecimal.
Stocarea tipurilor distincte
Prin apelarea metodei setXXX() din interfata PreparedStatemet se poate introduce un tip de date DISTINCT ca si parametru de intrare a unui obiect prepared statement. De exemplu, în cazul tipului de date MONEY poate fi utilizata metoda setBigDecimal().
Citirea tipurilor structurate
Totdeauna un obiect facând parte dintr - un tip de date structurat SQL poate fi salvata doar prin apelarea metodei getObject() din interfata ResultSet. Implicit, aceasta metoda returneaza o valoare de tip Struct pentru un tip structurat. De exemplu,
Struct struct = (Struct)rs.getObject(1); |
citeste o valoare Struct din prima coloana a rândului curent de result set. Interfata Struct contine metode pentru citirea atributelor de tip structurat cum ar fi un tablou de valori de tip Object. Implicit, un obiect Struct este considerat valid pe atâta timp cât aplicatia pastreaza referinta la el.
Stocarea tipurilor distincte
Prin apelarea metodei setObject() din interfata PreparedStatement se poate introduce un tip de date structurat ca si parametru de intrare a unui obiect prepared statement.
Elementele introduse în acest subcapitol reprezinta doar o trecere în revista a celor mai importante aspecte legate de lucrul cu bazele de date utilizând JDBC 2.0 API. Pentru implementarea unor astfel de idei se poate folosi documentatia pachetului javax.sql.
|