Sunteți pe pagina 1din 9

sql & java

Programare SQLJ
Cnd dorim s scriem un program care acceseaz o baz de date dintr-un program Java, ntrebarea este: Ce vom folosi, JDBC sau S !J"
Monica Cioat

n ultimii ani, Java a devenit limbajul preferat al dezvoltatorilor de aplicaii Internet/Intranet. Apleturile i servleturile Java apar peste tot pe Web, oferind o bogat funcionalitate unui mediu, p!n nu demult, eminamente static. "iturile Web au devenit veritabile furnizoare i colectoare de informaii, iar de cele mai multe ori aceste informaii trec printr#o baz de date. $eci accesarea unei baze de date este o problem care trebuie rezolvat de fiecare dat c!nd dorim s construim astfel de aplicaii. $ac ai mai accesat din Java baze de date, vei spune J$%& este soluia i nu v pot contrazice' dar pot spune c soluia J$%& poate fi acum ameliorat graie noii te(nologii ")*J menit s simplifice acolo unde e posibil modul de acces la baza de date.

Un exemplu
")*J este o cale standard de includere a comenzilor ")* statice direct +n programe Java. ,oua te(nologie este rezultatul unei colabor ri -racle, I%., "/base, 0andem i Informi1, dup modelul standardului A,"I/I"- de legare a comenzilor ")* +n programe &, &-%-*, 2-303A, sau alte limbaje. -racle implementase anterior 4ro5& un produs ce permite utilizarea comenzilor ")* +n programe &. &u alte cuvinte, ")*J ar fi un soi de 4ro5Java. $eoarece #ro$an%t&ing desemneaz o te(nologie 6specific 7/ proprietar -racle, iar ")*J este un standard desc(is, nu s#a ales denumirea de 4ro5Java. $up cum vom vedea +n acest articol, dei ")*J simplific scrierea, gestiunea i depanarea aplicaiilor Java, el nu +nlocuiete J$%&. $in contr , implementarea -racle pentru ")*J c(iar folosete J$%&. 4entru a +nelege cum funcioneaz ")*J s lu m urm torul e1emplu8 presupunem c avem o tabel , emp, +n baza de date care conine informaii despre angajaii unei firme, iar printre c!mpurile acesteia8 ename # numele i sal # salariul angajatului. $orim s afi m numele tuturor angajailor care au salariul mai mare dec!t o valoare dat . &odul J$%& +n acest caz ar putea fi8 // 64resupunem c avem deja un obiect J$%& &onnection conn7 // definim variabile Java "tring name' int id9:;<<=' float salar/9>????' // &onstruim un obiect J$%& 4repared"tatement. 4repared"tatement pstmt 9 conn.prepare"tatement 6@select ename from emp A(ere empno9B and salCB@7' pstmt.setInt6<, id7' pstmt.set2loat6>, salar/7' // D1ecutam o interogare' valorile obtinute sunt //asignate unei variabile Java. 3esult"et rs 9 pstmt.e1ecute)uer/67' A(ile 6rs.ne1t677 E name9rs.get"tring6<7' "/stem.out.println6@,umele este8 @ F name7' G rs.close67 pstmt.close67' 4rimele trei linii definesc variabilele Java name, id i salar/. Hrm toarea linie realizeaz un apel de preg tire a unei instruciuni 6prepared statement7. 4resupun!nd c deja este stabilit o cone1iune prin J$%& la baza de date, putem folosi metoda prepare"tatement67 # metod a obiectului conn derivat din clasa &onnection 6cone1iune7. #reparedStatement este folosit atunci c!nd +n interiorul comenzii ")* avem nevoie de un set dinamic de valori, ceea ce +nseamn c o aceeai instruciune gata preg tit 6prepared statement7 poate fi folosit de oric!te ori pentru diferite valori ale variabilelor. Interogarea este format +ntr#o instan 6pstmt7 a clasei 4repared"tatement +n timp valorile variabile sunt p strate +n variabile Java i transmise prin apelurile pstmt.setInt67 i pstmt.set2loat67. 4rimul @B@este +nlocuit cu valoare variabilei id, deci un int a c rui valoare este :;<<=. Al doilea @B@ este +nlocuit cu valoarea variabilei salar/ 6un float a c rui valoare este >????7. Hrmeaz e1ecuia interog rii, datele rezultat fiind returnate +ntr#un obiect 3esult"et al J$%&. n final, datele sunt e1trase din setul rezultat i afiate. Hn set rezultat

conine de obicei mai multe linii de date, dar +n acest e1emplu avem o singur linie. $up cum se poate lesne constata, avem destul de lucru pentru a realiza o simpl interogare. ,e putem imagina atunci comple1itatea apelurilor ")* multilinie +n care avem mai multe variabile Java. Inevitabil dup un timp ne vom pune +ntrebarea @Cum putem face ca din Java interogrile s fie mai u'or de realizat"@ "implificarea procesului de interogare Aa cum b nuii deja r spunsul la +ntrebarea noastr este8 folosind S !J. 4entru a ne da seama de avantajele ")*J s transcriem e1emplul de mai sus folosind ")*J8 "tring name' int id9:;<<=' float salar/9>????' IsJl Eselect ename into 8name from emp A(ere empno98id and salC8salar/7' "/stem.out.println6@,ame is8 @ F name7' &e observ m analiz!nd acest codB 4rimul lucru, un cod mult mai concisK D1plicaiaB ")*J permite comenzilor ")* s fie legate direct +n codul Java i accept ca variabilele Java s fie folosite direct +n comenzile ")*. .ai observ m c fiecare variabila Java este precedat de dou puncte @8@ i c prin intermediul acestor variabile Java putem e1trage cu uurin rezultatul interog rii, dac ... numai dac rezultatul e1ecuiei comenzii ")* este o reprezentat de o singur linie 6o +nregistrare7K

Componentele SQLJ
n continuare, +n paralel cu e1plicarea pailor pe care#i face/ascunde ")*J vom +ncerca s identific m componentele interne ale ")*J i s vedem rolul pe care#l joac fiecare. 0ranslatorul ")*J Aceast component nu este altceva dec!t un preprocesor sau un precompilator scris complet +n Java, i care este rulat dup ce a fost creat sursa ")*J 6un fisier .sJlj7. 0ranslatorul accept comenzi ")* +n interiorul comenzilor e1ecutabile ")*J. &omenzile e1ecutabile ")*J, ca i declaraiile ")*J, sunt precedate de IsJl i pot fi combinate cu cod Java +n fiierul surs sJlj. ntr#o prim etap translatorul face o analiz sintactic i semantic a comenzilor ")* legate, eventualele erori put!nd fi depistate +nc din aceast faz . Aceasta verificare se poate face conectat sau nu la baza de date 6on-line sau off-line(, +n funcie de opiunile setate. $ac se face o verificare on-line, ")*J se conecteaz la baza de date i verific e1istena tabelelor, a procedurilor stocate i compatibilitatea tipurilor coloanelor referite cu a variabilelor gazd din Java. ,u acelai lucru se +nt!mpl cu codul J$%& care, fiind pur Java, este compilat direct. &ompilatorul nu tie nimic despre ")*, prin urmare erorile ")* nu vor putea fi depistate dec!t la e1ecuie. n faza urm toare translatorul proceseaz codul ")*J, convertete operaiile ")* +n apeluri ")*J runtime, genereaz codul de ieire i unul sau mai multe profile S !J. Dste generat un profil separat pentru fiecare cone1iune, acolo unde se fac cone1iuni 6de e1emplu, la baze de date diferite, sau +n sc(eme diferite7 i fiecare comand ")* va avea mapat o intrare +n profilul generat pentru cone1iunea pe care o folosete. 0ranslatorul genereaz un fiier .java care conine8 # clasele definite i codul Java din fiierul surs .sJlj' # definiiile claselor create ca rezultat al declaraiilor ")*J' # o definiie de clas pentru o clas specializat 6numit i clas profile-)e%7, clase pe care ")*J le creaz i le folosete +n conjuncie cu profilele generate' n final este apelat un compilator Java, care poate fi de e1emplu J$L#ul de la "un i se genereaz c!te un fiier .class pentru fiecare clas definit , c!te un .class pentru fiecare declaraie ")*J i c!te un .class pentru fiecare clas de tip profil c&eie. 4rofilele generate conin informaii despre toate comenzile ")* coninute +n codul surs , tipurile de date care se folosesc i tabelele accesate. &!nd aplicaia ruleaz sunt accesate profilele pentru a se obine operaiile ")* i a le transmite driverului J$%&. Implicit profilele sunt puse +n fiiere de resurse serializate .ser, dar se pot converti +n fiiere .class tot +n procesul de translaie. 6*bserva+ie8 unele broAsere, de e1. ,etscape ,avigator M.1 nu suport fiiere de resurse cu e1tensia ,ser. 4entru a rezolva aceast problem se utilizeaz o opiune de conversie #ser>class care are ca efect conversia resurselor +n fiiere .class7. ")*J runtime &omponenta runtime este apelat de fiecare dat c!nd este rulat o aplicaie ")*J. *a r!ndul ei scris complet +n Java, aceast component implementeaz aciunile descrise de operaiile ")* i acceseaz baza de date folosind un driver J$%&. "tandardul ")*J nu specific ca la rulare s se foloseasc un driver J$%& pentru accesarea bazei de date, +ns -racle ")*J are nevoie de un astfel de driver. &(iar mai mult, este necesar un driver -racle dac aplicaie folosete construcii proprii -racle.

Elemente de lim aj SQLJ


&omenzile ")*J +ncep cu construcia IsJl i se +mpart +n dou categorii8 6<7 declara+ii de iteratori' iteratorii sunt similari cu seturile rezultat din J$%& i folosii pentru e1tragerea rezultatelor interog rilor multi#linie sau declara+ii de cone-iuni +n diferite sc(eme ale mai multor baze de date' 6>7 comenzi e-ecutabile, folosite pentru e1ecutarea operaiilor ")*' $eclaraiile ")*J pot s apar +n fiierul surs +n afara claselor, +n clase, +n clase +ncuib rite, +ns nu 'i n interiorul metodelor. $e e1emplu8 $eclaratie ")*J' //legal &lass -uter E $eclaratie ")*J' //legal &lass Inner E $eclaratie ")*J' //legal G void func67 E $eclaratie ")*J' // Ilegal G G &one1iuni 0oate drivere -racle +ntrein clasa oracle.jdbc.driver.-racle$river. 4entru conectarea la baza de date se poate folosi unul sau mai multe drivere. 4entru stabilrea cone1iunii la baza de date se poate folosi metoda connect67 a clasei oracle.sJlj.runtime.-racle, pentru care vor trebui specificate8 driverul folosit, url#ul bazei de date, numele i parola utilizatorului, pentru identificarea sc(emei +n care se va face cone1iunea. Iat un e1emplu8 -racle.connect6@jdbc8oracle8t(in8Nlocal(ost8<=><8orcl@, @scott@, @tiger@7' 4arametrii cone1iunii pot fi specificai +ntr#un fiier de proprietai, connect.properties, care va fi referit la apelul metodei8 -racle.connect6 ./&lass.class, @connect.properties@7' // ./&lass este numele clasei. $ac vrem s facem mai multe cone1iuni la baze de date diferite sau +n sc(eme diferite ale aceleiai baze de date, vom construi pentru fiecare cone1iune c+te o instan a clasei $efault&onte1t8 $efault&onte1t ct1< 9 -racle.get&onnection 6@jdbc8oracle8t(in8Nlocal(ost<8<=><8orcl<@, @scott@, @tiger@7' $efault&onte1t ct1> 9 -racle.get&onnection 6@jdbc8oracle8t(in8Nlocal(ost>8<=><8orcl>@, @bill@, @lion@7' "unt dou modalit i de a sc(imba +ntre cele dou cone1iuni8 # prin specificarea e1plicita a cone1iunii folosite8 IsJl Oct1<P E ")* operation G' ... IsJl Oct1>P E ")* operation G' sau8 # prin setarea unei cone1iuni ca fiind cone1iunea implicit folosind metoda static set$efault&onte1t67 a clasei $efault&onte1t8 $efault&onte1t.set$efault&onte1t6ct1<7' ... IsJl E ")* operation G' // comenzi pentru ct1< IsJl E ")* operation G' IsJl E ")* operation G' ... $efault&onte1t.set$efault&onte1t6ct1>7' ... IsJl E ")* operation G' // comenzi pentru ct1> IsJl E ")* operation G' IsJl E ")* operation G' ...

"e pot utiliza cone1iuni diferite la translaie i runtime i asta fiindc aplicaia final va folosi un alt mediu. n acest caz se pot folosi opiuni +n linia de comand +n care se lanseaz +n e1ecuie translatorul 6folosind comanda sJlj7, prin care s se specifice H3*#ul i tipul driverului folosit 6dup opiunea #url7, utilizatorul 6#user7 i parola 6#passAord7. Iteratori Iteratorii sunt folosii pentru recepionarea datelor unei interog ri. Iteratorul trebuie construit +n aa fel +nc!t s fie compatibil cu datele care va trebui s le recepioneze, at!t +n ceea ce privete tipul c!t i num rul c!mpurilor lor. "inta1a folosit va fi8 I")* QmodificatoriCiterator numeRclasaRiteratorEtip declaratiiG' .odificatorii sunt opionali i pot fi orice modificatori Java standard ca8 public, static, etc. "unt dou tipuri de iteratori8 iteratori cu nume i pozi+ionali. n cazul interatorilor cu nume trebuie specificate numele 6identic cu al coloanei de unde se iau datele7 i tipul, care de asemenea trebuie s fie compatibil cu al coloanei respective. IsJl public iterator DmpIter6"tring ename, double sal7' 4entru iteratorii pozi+ionali se va specifica numai tipul coloanelor8 IsJl public iterator DmpIter6"tring, double7' n ambele cazuri translatorul creeaz clasa public DmpIter, cu dou atribute. n declaraia oric rei clase iterator se pot specifica una sau mai multe interfee care vor fi implementate de clasa generat , folosind urm toarea sinta1 8 Isql QmodificatoriC iterator numeRclasaRiterator implements interfata<, interfata>,S interfata, 6declaratii de tip7' i se pot specifica i iniializa una sau mai multe constante care s fie incluse +n definiia clasei generate. &onstantele sunt public static final. "e folosete urm toarea sinta1 8 !sql QmodificatoriC iterator numeRclasaRiterator "it# 6var<9valoare<,S,var,9valoare,7 6declaratii de tip7' *bserva+ie8 &lauzele Ait( i implements sunt plasate +ntotdeauna +naintea declaraiilor de tip. Acolo unde apare i clauza Ait( si implements, clauza implements va fi plasata prima. *ista de dup Ait( va fi prins +ntre paranteze. D1emplu8 IsJl public iterator ./Iter Ait( 60T4D&-$D9-racle0/pes.,H.%D37 6"tring empname, int empnum7' &lasa declarat ./Iter, va avea un atribut 0T4D&-$D care va fi public static final de tip int i iniializat cu valoarea t/pecode pentru tipul de date ,H.%D3 aa cum este definit +n clasa -racle J$%& oracle.jdbc.driver.-racle0/pes. D1emplul urm tor conine at!t clauzele implements c!t i Ait(. IsJl public iterator ./Iter implements m/pacUage../IterIntfc Ait( 6(oldabilit/9true7 6"tring empname, int empnum7' &omenzi ")*J e1ecutabile - comand ")*J e1ecutabil este o comand ")* suportat de driverul J$%& folosit 6comenzi $.*, $$*, sau de control al tranzaciilor7 precedat de clauza ")*J IsJl. &omenzile e1ecutabile trebuie s respecte urm toarele reguli8 # pot s apar n codul Java oriunde este permis un bloc 6deci +n interiorul definiiei metodelor i a blocurilor statice de iniializare7' # trebuie prinse ntre acolade8 E...G. # tot ce este cuprins ntre acolade se consider o comand e-ecutabil S !J i trebuie s respecte regulile de sinta1 ")*, cu e1cepia e1presiilor gazd Java. Iat un e1emplu8 IsJl E ")* operation G' // pentru comenzi care nu au iesire, de e1emplu I,"D30 IsJl result 9 E ")* operation G' // pentru comenzi care au iesire, de e1emplu "D*D&0 *bserva+ie8 ,umai operaiile $.* 6"D*D&0, H4$A0D, I,"D30 i $D*D0D7 pot fi analizate i verificate sintactic de translatorul ")*J, translator folosind cone1iunea la baza de date. &omenzile $$* 6cum sunt &3DA0D ..., sau A*0D3...7, comenzile de control al tranzactiilor 6&-..I0 sau 3-**%A&L7, sau orice alt comand ")* nu va putea fi verificat . 4resupunem c tabela D.4 a fost creat cu comanda8

&3DA0D 0A%*D D.4 6D.4,A.D &VA36:?7,"A*A3T ,H.%D3 7' - comand de inserare +n tabel poate fi8 IsJl E I,"D30 I,0- emp 6empname, salar/7 WA*HD" 6XJoeX, M:???7G' $ac dorim ca operaia de inserare s fie f cut +ntr#o sc(em spre care avem stabilit o alt cone1iune, diferit de cea implicit , cu numele ct1, comanda va fi8 IsJl Oct1P E I,"D30 I,0- emp 6empname, salar/7 WA*HD" 6XJoeX, M:???7 G' n cadrul comenzilor e1ecutabile pot s apar i blocuri 4*/")*, +ntre acolade, e1act ca i orice alt comand ")*. IsJl E $D&*A3D n ,H.%D3' %DYI, n 89 <' WVI*D n Q9 <?? *--4 I,"D30 I,0- emp 6empno7 WA*HD"6>??? F n7' n 89 n F <' D,$ *--4' D,$' G' n interiorul ciclului se insereaz +nregistr rii noi care vor avea +n c!mpul empno valori de la >??< la ><??. n continuare vom lua un alt e1emplu de comand , care folosete e1presii gazd Java precedate de 687. D1presiile gazd sunt folosite pentru transmiterea valorilor +ntre codul Java i comenzile ")*. Acestea pot fi +n cazul cel mai simplu o simpl variabil Java, dar pot s fie i apeluri de metode care returneaz valori, valori ale c!mpurilor clasei, tablouri de elemente, e1presii condiionale de forma 6a B b 8c7, e1presii logice, sau e1presii la nivel de bit 6 bit.ise e-pressions7. Dle pot fi de intrare 6I,7, de ieire 6-H07 sau de intrare#ieire 6I,-H07. IsJl E H4$A0D emp "D0 sal 9 8salar/ WVD3D ename 9 8name G' *bserva+ie8 n ambele cazuri e1presiile Java sunt de tip I,, dar se poate specifica i e1plicit8 IsJl E H4$A0D emp "D0 sal 9 8I, salar/ WVD3D ename 9 8I, name G' &!nd o interogare returneaz o singur linie, ")*J permite specificarea unor variabile gazd Java, +n interiorul comenzii ")*, pentru e1tragerea rezultatului interog rii8 IsJl E "D*D&0 e1pression<,..., e1pression, I,0- 8 (ostRe1p<,..., 8(ostRe1p, 23-. datasource Qoptional clausesC G' $ac comanda "D*D&0 I,0- +ntoarce mai mult de un rezultat se va genera eroare8 "tring empname' ... IsJl E "D*D&0 ename I,0- 8empname 23-. emp WVD3D enum 9 >Z[=[ G' *bserva+ie8 -H0 este implicit pentru o lista I,0-, dar se poate specifica i e1plicit8 IsJl E "D*D&0 ename I,0- 8-H0 empname 23-. emp WVD3D enum 9 >Z[=[G' $e cele mai multe ori interog rile pe o tabel a bazei de date +ntorc mai multe linii ale tabelului. /n acest caz datele vor fi recep+ionate n iteratori, care trebuie mai +nt!i preg tii special, specific!ndu#li#se coloanele i tipul acestora, spre deosebire de obiectul 3esult"et din J$%&, care este instaniat generic. n J$%& clasa java.sJl.3esult"et poate conine, +n principiu, orice num r de coloane de orice tip. IsJl iterator "al,amedIter 6"tring empname, float neAsalar/7 ... class ./&lass E void func67 t(roAs ")*D1ception E ... "al,amedIter niter 9 null' IsJl niter 9 E "D*D&0 name A" empname, oldsal F raise A" neAsalar/ 23-. empsal G' ... G G 4utem declara i un iterator pozitional8 IsJl iterator "al4osIter 6"tring, float7' ...

class ./&lass E void func67 t(roAs ")*D1ception E ... "al4osIter piter 9 null' IsJl piter 9 E "D*D&0 name, oldsal F raise 23-. empsal G' ... G G Iat i c!teva reguli8 # ,u este indicat utilizarea unei sinta1e "D*D&0 5 pentru popularea unui iterator. # n cazul iteratorului poziional num rul de coloane, tipul i ordinea lor din iterator trebuie s coincid cu num rul coloanelor tabelului. # n cazul iteratorilor cu nume este posibil ca num rul coloanelor iteratorului s fie mai mic dec!t al coloanelor tabelului' +n acest caz, dac la translatare nu se folosete opiunea #Aarn9nostrict se va da o atenionare. # Iteratorii poziionali i cei cu nume sunt diferii i incompatibili cu orice tip de clase Java. # Hn iterator de un anumit tip nu poate fi convertit +ntr#un iterator de alt tip' # &oninutul unui iterator, similar cu un set rezultat, este determinat numai de starea bazei de date +n momentul e1ecuiei "D*D&0#ului care#l populeaz ' # Actualiz rile, inserarile, tergerile, commit#urile sau rollbacU#urile nu afecteaz iteratorii sau coninutul lor.

$teratori cu nume vs% iteratori po&i'ionali


n general pentru utilizarea unui iterator se parcurg urm torii pai8 6<7 2olosirea unei declaraii ")*J pentru definirea clasei iteratorului 6tipului iteratorului7' 6>7 $eclararea unei variabile de tipul respectiv' 6:7 4opularea variabilei iterator cu rezultatul unei interog ri cu "D*D&0 ' 6M7 Accesarea coloanelor interog rii iteratorului. 6modalitatea de acces depinde de tipul iteratorului, pozitional sau numit7. 6=7 &!nd procesarea rezultatelor s#a terminat, iteratorul este +nc(is. Iteratorii cu nume confer o mai mare fle1ibilitate prelucr rii deoarece selecia datelor se face prin numele c!mpurilor iteratorului. &oncret, pentru fiecare c!mp este construit automat o metod de acces la valoarea acestuia, nemaifiind necesar respectarea locului/ordinii c!mpurilor tabelului. *a definirea iteratorilor cu nume trebuie respectate urmatoarele reguli8 # ,umele coloanelor s nu fie cuvinte rezervate Java' # &oloanele s nu aib acelai nume cu metodele folosite de clasele iterator# ne1t67, close67,get3esult"et67, is&losed67. # ,umele coloanelor s nu fie identice cu numele tabelelor i s fie diferite +ntre ele' n cazul iteratorilor poziionali selecia datelor se face prin poziia c!mpului, ceea ce face ca +n acest caz accesul la datele elementare s se realizeze mai greoi. $atele trebuiesc +nc rcate direct +n e1presii gazd Java cu comanda 2D0&V I,0- i e1presiile gazd trebuie s fie +n ordinea corect . 4resupunem c dorim s popul m un iterator cu date din tabelul8 &3DA0D 0A%*D 43-JD&0" 6I$ ,H.%D36M7, ,A.D WA3&VA36:?7, "0A30R$A0D $A0D,$H3A0I-, ,H.%D36:7 7' $eclararea unei variabile iterator si popularea ei se face prin8 IsJl public iterator 4rojIter 6"tring projname, int id, $ate deadline7' 4rojIter projs' IsJl projs 9 E"D*D&0 startRdate F duration A" deadline, name, id 23-. projects WVD3D startRdate F duration C9 s/sdateG' .etoda ne1t67 este comun pentru toi iteratorii i joac acelai rol ca i metoda ne1t67 pentru un obiect 3esult"et din J$%&, +ntorc!nd true dac e1ist linia i mutindu#se la urm toarea linie de date din setul rezultat. $atele din fiecare linie sunt accesate apelind metoda iterator ce are acelasi nume cu al coloanei. IsJl projs 9 E "D*D&0 startRdate F duration as deadline, projname, id 23-. projects WVD3D startRdate F duration C9 s/sdate G' // 4rocesarea rezultatelor

A(ile 6projs.ne1t677 E "/stem.out.println6@4roject name is @ F projs.projname677' "/stem.out.println6@4roject I$ is @ F projs.id677' "/stem.out.println6@4roject deadline is @ F projs.deadline677' G // nc(ide iteratorul projs.close67' ... n cazul iteratorilor poziionali se va specifica numai tipul coloanelor' pentru obinerea datelor din iteratorii poziionali se va folosi comanda 2D0&V..I,0- urmat de un apel al metodei end2etc(67 care va determina dac s#a ajuns la sf!ritul datelor. $e e1emplu8 IsJl public iterator DmpIter 6int, "tring, float7' // $eclar m i iniializ m variabile gazd int id9?' "tring name9null' float salar/9?.?f' DmpIter emps' IsJl emps 9 E "D*D&0 empnum, empname, empsal 23-. emplo/eesG' A(ile 6true7 E IsJl E 2D0&V 8emps I,0- 8id, 8name, 8salar/ G' if 6emps.end2etc(677 breaU' // Acest test trebuie facut dup fetc(, // dar +nainte de procesarea rezultatelor. "/stem.out.println6@,ame is @ F name7' "/stem.out.println6@Dmplo/ee number is @ F id7' "/stem.out.println6@"alar/ is @ F salar/7' ... G emps.close67' ... -bservaii8 # ,u este necesar utilizarea e1plicita a metodei ne1t67 pentru pozitionarea iteratorului, deoarece apelurile 2D0&V mut implicit iteratorul pe urm toarea linie/+nregistrare. # Iniial metoda end2etc(67 returneaz true +nainte ca liniile s fie +nc rcate, iar dup ce o linie a fost +nc rcat cu succes va returna false p!n c!nd i ultima linie va fi +ncarcat , dup care va returna din nou true. # .etoda end2etc(67 trebuie apelat +nainte ca setul rezultat s fie procesat, deoarece 2D0&V nu depisteaz e1cepiile ")* c!nd ajunge la sf!ritul datelor'

Comen&i de asignare (SE)*


")*J ne permite s atribuim o valoare unei e1presii gazd Java +n interiorul comenzilor ")*. &omanda de asignare va avea urm toarea sinta1 8 IsJl E "D0 8 (ostRe1p 9 e1pression G' (ostRe1p este e1presia gazd , de e1emplu o variabil sau un tablou de indeci. e-pression poate fi un num r, o e1presie gazd sau o e1presie aritmetic , un apel de funcie. Implicit e1presiile gazd sunt de ieire -H0 dar acest lucru se poate specifica e1plicit8 IsJl E "D0 8-H0 (ostRe1p 9 e1pression G' $ac folosim I, sau I,-H0 se va genera eroare +n faza de translatare. &omanda anterioar este funcional ec(ivalent cu8 IsJl E %DYI, 8-H0 (ostRe1p 89 e1pression' D,$' G' Hn e1emplu de asignare8 IsJl E "D0 81 9 foo<67 F foo>67 G' Waloarea atribuit lui 1 este suma valorilor returnate de funciile foo<67 i foo>67 # se presupune c tipul lui 1 e compatibil cu tipul celor dou funcii.

+pelul procedurilor ,i -unc'iilor stocate


2unciile i procedurile stocate pot fi scrise +n Java, 4*/")* 6+n -racle7, sau orice alt limbaj de programare acceptat de baza de date utilizat . 4entru apelul procedurilor se va folosi comanda &A**8 IsJl E &A** 43-&6Q 4A3A.R*I"0C7 G' 43-& este numele procedurii stocate, opional poate s aib parametrii care pot s fie de intrare, ieire sau intrare# ieire. 4resupunem c avem definit procedura 4*/")*8 &3DA0D -3 3D4*A&D 43-&D$H3D .A\R$DA$*I,D 6deadline -H0 $A0D7 I" %DYI, "D*D&0 .A\6startRdate F duration7 I,0- deadline 23-. projects' D,$' n ")*J apel m procedura .A\R$DA$*I,D astfel8 java.sJl.$ate ma1$eadline' ... IsJl E &A** .A\R$DA$*I,D68out ma1$eadline7 G' 2unciile stocate returneaz o valoare i eventual au o list de parametrii care pot fi de intrare, ieire sau intrare# ieire. Apelul funciilor se face prin utilizarea comenzii WA*HD". n ")*J standard, funciile trebuie s fie prinse +ntre paranteze rotunde. n -racle acest lucru este opional. IsJl result 9 E WA*HD"6 2H,&6Q 4A3A.R*I"0C77 G' *bserva+ie8 $ac dorim ca aplicaia s fie compatibil cu -racle;, la funcii nu se vor pune paranteze dac lista parametrilor este vid . IsJl E &A** .A\R$DA$*I,D G' //da IsJl E &A** .A\R$DA$*I,D67 G' //nu Controlul tran&ac'iilor At!t +n ")*J c!t i +n J$%& se poate lucra tranzacional. &ontrolul tranzaciilor se poate face automat sau manual. "e poate specifica utilizarea unui commit automat prin setarea unui flag auto-commit +n momentul definirii cone1iunii ")*J, specific!nd true pentru ultimul parametru al metodelor8 -racle.connect67 sau -racle.get&onnection678 -racle.get&onnection6@jdbc8oracle8t(in8Nlocal(ost8<=><8orcl@, @scott@, @tiger@, true7' sau folosind setAuto&ommit67 obiectului J$%& &onnection, dac cone1iunea a fost deja creat ' ct1.get&onnection67.setAuto&ommit6false7' ct1.get&onnection67.setAuto&ommit6true7' "e poate realiza un control manual al comenzilor tranzaciei folosind comenzile ")*J commit i rollbac)8 IsJl E commit G' IsJl E rollbacU G' Dvident c dac se seteaz un commit automat comenzile e1plicite commit sau rollbacU nu#i mai au rostul. &ommit#urile, fie ele automate sau manuale i rollbacU#urile nu afecteaz seturile rezultat desc(ise i iteratorii. " consider m de e1emplu cazul +n care dorim s facem un "D*D&0, apoi un H4$A0D, iar apoi un &-..I0. Hn set rezultat sau un iterator populat de comanda "D*D&0 nu va fi afectat de H4$A0D i nici de &-..I0. $ac facem mai +nt!i un H4$A0D, apoi "D*D&0 i 3-**%A&L, setul rezultat sau iteratorul populat de "D*D&0 va conine datele actualizate, f r a lua +n considerare 3-**%A&L#ul.

Unde -olosim SQLJ


$up ce am v zut ce este, cum putem s folosim ")*J, r m!ne s stabilim unde poate fi utilizat sau altfel spus c!nd vom apela la ")*J. $eoarece implementarea -racle a ")*J folosete J$%& pentru a comunica cu baza de date, programatorii ")*J se pot bucura de aceeai fle1ibilitate ca i programatorii J$%& +n dezvoltarea aplicaiilor. -racle ofer trei tipuri de drivere J$%&8 un driver sub+ire 6t(in7 <??] pur Java, un driver *C0 6-racle &all Interface7 i un server-side driver 6 @L43%@ Lernel 43ogram %undled7. 4utem folosi oricare din aceste drivere, la fel de bine cum se pot folosi i altele construite de ali produc tori. $e e1emplu, se poate folosi ")*J +ntr#un applet care ruleaz +ntr#un broAser, i care folosete un t&in driver 6de numai :??L7. &a alternativ putem folosi ")*J +ntr#un client sau +ntr#un nivel din mijloc al aplicaiei folosind driver -&I driver 6care poate oferi mai multe avantaje comparativ cu un t&in driver, dar i dezavantajul faptului c are o parte ce trebuie +n prealabil instalat pe client7 sau se poate folosi ")*J pe partea server, +n proceduri i funcii stocate Java, triggere, Dnterprise Java%eans sau obiecte &-3%A. Accesul se face prin -racle J$%& site#server. -racleZi

"erver include un translator ")*J, ceea ce +nseamn c fiierele surs de pe partea server pot fi translatate direct pe server. n crearea unei aplicaii pentru -racleZi "erver sunt mici diferene +ntre codul care va fi folosit pe partea server i cel de pe client8 # putem avea o singur cone1iune, care trebuie s ofere acces la baza de date +n care codul ruleaz ' # cone1iunea este implicit , aadar nu trebuie specificat e1plicit, # spre deosebire de cone1iunile client, cone1iunea de pe server nu poate fi +nc(is . &odul se poate translata i compila at!t pe partea client cit si pe server. $ac acest lucru este realizat pe client, se pot +nc rca fiierele .class i de resurse de pe server pe propria main , sau folosind translator de pe server. ntrebarea care se pune +n acest moment ar putea fi8 @Dac S !J este mai avanta1os dect JDBC, de ce s mai folosim JDBC"@ n momentul de fa ")*J i J$%& sunt A4I#uri complementare. ")*J poate fi folosit numai pentru ")*#uri statice, deci c!nd comanda ")* este cunoscut +n momentul dezvolt rii. $e regul marea majoritate a comenzilor ")* sunt statice, iar pentru comenzile ")* dinamice, construite +n timpul rul rii, se va folosi J$%&. $in acest punct de vedere nu e1ist probleme fiindc dac este necesar +n interiorul unei aplicaii ")*J se pot folosi i construcii J$%&.

Conclu&ii
4rogramatorii Java au la dispoziie pentru accesarea bazelor de date dou alternative8 J$%& sau ")*J. "ingur J$%& poate fi suficient dar are dou sl biciuni8 # codul este lung i greoi, interog rile realiz!ndu#se destul de dificil' # erorile din interiorul operaiilor ")* nu pot fi depistate dec!t la rulare. ")*J rezolv ambele probleme8 # permite comenzilor ")* cu variabile Java s apar direct +n comenzi ")*J, simplific!nd codul i f c!ndu#l mai clar. # translatorul ")*J verific sinta1a i semantica comenzilor ")*, permi!nd depistarea erorilor +nainte de rulare. n plus, ")*J asigur aceleai verific ri la rulare ca i J$%&. n general J$%& i ")*J vor fi v zute ca te(nologii complementare deoarece8 # ")*J foloseste J$%& pentru a comunica cu baza de date +n timpul translat rii 6dac folosim verific rile online7 i rularii. # J$%& este necesar pentru comenzile ")* dinamice, unde operaiile ")* sunt determinate pe parcursul rul rii aplicaiei' # "e poate mi1a codul aceluiai program +ntre cod J$%& i cod ")*J. Ambele te(nologii pot fi folosite la orice nivel8 # +ntr#un aplet ce foloseste, de e1emplu, un driver t(in J$%&, # +ntr#o aplicaie pe partea client sau # la nivelul din mijloc, folosind un driver t(in sau un driver -racle -&I' # +ntr#o procedura stocat , obiecte &-3%A sau Java%eans care ruleaz +n -racleZi i care folosesc -racle server# side J$%& driver.

S-ar putea să vă placă și