Solutii de dezvoltare a aplicatiilor de interactiune cu baze de date
Ce sunt procedurile stocate si cum sunt implementate īn Oracle 8i procedurile stocate Java. Avantajele utilizarii acestei tehnologii, cāteva detalii despre implementarea masinii virtuale Java realizata īn serverul Oracle 8i si un exemplu concret de dezvoltare si punere īn exploatare a unei proceduri stocate scrise īn Java.
Va mai aduceti aminte de primele aplicatii ale limbajului Java? Imagini animate, sunet, interactivitate, si toate prin intermediul unui simplu program de navigare WWW, pe orice platforma si sistem de operare. Istoria Java a īnceput īn 1995, iar īn cei patru ani care au trecut s-au produs foarte multe schimbari, datorate mai ales implicarii īn universul Java a unor colosi din industria calculatoarelor: SUN, IBM, Oracle. Platforma Java a evoluat dintr-un mediu interesant pentru mediile academice īntr-un adevarat mediu de īntreprindere, evolutia datorāndu-se atāt calitatilor intrinseci ale platformei, cāt si noilor oportunitati de afaceri pe care le ofera.
Acest articol nu-si propune sa descrie calitatile limbajului si platformei Java. S-au scris destule materiale de calitate despre asa ceva, drept care acest articol īsi propune sa descrie una din cele mai elegante si performante (da, nu va mirati, performanta a īnceput sa apara si īn lumea aplicatiilor Java!) solutii de dezvoltare a aplicatiilor de interactiune cu baze de date: procedurile stocate Java (Java Stored Procedures).
Motivatie
Procedurile stocate Java sunt o urmare fireasca a efortului de īmbunatatire a calitatii solutiilor pentru mediile industriale. Aplicatiile client/server au permis separarea logicii programului si alegerea sistemului de operare cel mai potrivit pentru fiecare sectiune a aplicatiei: mediile Windows pentru preluarea si afisarea informatiilor si mediile Unix pentru gestiunea si protectia informatiilor. Problemele de portabilitate si costurile ridicate ale īntretinerii variantelor aplicatiilor folosite de clienti au fost rezolvate 929n1311j o data cu aparitia platformei Java si a applet-urilor. Acelasi cod poate sa ruleze pe orice platforma hardware, iar aplicatia poate fi descarcata direct de pe server, deci se va folosi īntotdeauna ultima versiune a aplicatiei client. Asadar, 100% Java.
Introducerea conceptului de server de aplicatii si dezvoltarea arhitecturii pe trei niveluri au reprezentat pentru Java noi rampe de lansare. La ora actuala, nu mai exista server de aplicatii care sa nu ofere suport pentru servluri, aceste mini-aplicatii care ruleaza īn cadrul serverului de aplicatii si genereaza pagini HTML pentru clientii universali: programele de navigare. Īn curānd vom auzi si de implementari de Java Server Pages, o replica la mai cunoscutele Active Server Pages, care reprezinta o modalitate foarte simpla de a īncapsula cod Java īn cadrul unei pagini HTML. Aceste doua tehnologii trebuie puse īn conjunctie cu tehnologiile de obiecte distribuite (CORBA) sau componente Java (Enterprise Java Beans), care sunt si ele prezente īn cele mai noi servere de aplicatii. Pāna acum, 200% Java.
Dar producatorii de sisteme de baze de date nu s-au oprit aici. Oracle, prin ultima versiune a sistemului de gestiune a bazelor de date, Oracle 8i, īmpinge mai departe platforma Java: direct īn baza de date! Sunt implementate nu numai conceptele legate de proceduri stocate īn Java, ci si componente Java pentru īntreprindere (EJB). Toate acestea, pentru ca noul mare val de aplicatii va fi reprezentat de cele bazate pe tehnologiile Internet si Intranet. Īn total, 300% Java, asa cum este unul din sloganurile corporatiei Oracle.
Aceasta scurta enumerare de solutii si posibilitati trebuie sa va faca sa va gānditi la cel putin doua aspecte. Mai īntāi, Java exista si este folosit pentru implementarea de mari proiecte informatice datorita multiplelor avantaje si standarde adoptate īn jurul platformei. Al doilea aspect, poate mai important, este ca un singur limbaj de programare poate fi folosit pentru dezvoltarea tuturor tipurilor de programe de care este nevoie īntr-o īntreprindere: aplicatii client, comunicatii, securitate, module pentru serverul de aplicatii, accesul la baze de date, multimedia, gestiunea retelei si lista ar putea continua. Decizia de migrare spre Java poate lua un pic de timp, dar avantajele sunt clare. As dori sa subliniez, īn afara de cele deja clasice, crearea unei expertize de programare īntr-un singur limbaj īn cadrul īntreprinderii care va īmbunatati calitatea tuturor aplicatiilor scrise. Nu mai este nevoie de C/C++, VB, Perl, PL/SQL, COBOL, ci doar de Java si de API-urile ei.
Revenind la subiectul articolului, īn cadrul articolului voi prezenta modalitatea prin care sunt implementate īn Oracle 8i procedurile stocate Java. Prezentarea se va axa pe particularitatile aceste solutii, incluzānd avantajele, restrictiile, modul de dezvoltare, testare si de apel.
Prima īntrebare la care trebuie dat un raspuns este ...
Ce sunt procedurile stocate Java?
Pot fi date mai multe definitii, fiecare dintre ele surprinzānd un anume aspect al procedurilor stocate. Primul aspect care merita atins este cel algoritmic. Procedura stocata, fie ea īn Java sau īn traditionalul PL/SQL, reprezinta o implementare a unui algoritm, o extensie a limbajului SQL. Limbajul SQL este foarte bun pentru definirea, manipularea si interogarea datelor dintr-o baza de date, dar este lipsit de unele constructii necesare pentru crearea de programe. Din acest motiv, este necesara utilizarea unui limbaj extern, de preferat de nivel īnalt, pentru a putea descrie usor algoritmii folositi īn prelucrarea datelor. Aici intervin procedurile stocate care extind functionalitatea motorului bazei de date.
Īnainte de a trece la alte caracteristici ale procedurilor stocate, trebuie mentionat ca termenul se refera atāt la proceduri (constructii de programare care primesc parametrii, dar nu īntorc o valoare), cāt si la functii, pentru care este importanta valoarea īntoarsa.
Al doilea aspect al procedurilor stocate īn Java este legat de modul de executie. Codul procedurii, deci aplicatia īn final, foloseste o implementare de masina virtuala foarte performanta, complet integrata īn SGBD. Aceasta masina virtuala este o implementare scalabila si de nivel īntreprindere a platformei Java. Asadar, procedura stocata Java este o modalitate de a beneficia de avantajele oferite atāt de Java, cāt si de implementarea performanta din serverul bazei de date Oracle 8i. Masinii virtuale Java oferite de Oracle, numita Aurora, īi voi dedica o sectiune speciala datorita caracteristicilor ei particulare.
O alta caracteristica importanta a procedurilor stocate este faptul ca este reprezinta o modalitate de a centraliza logica aplicatiei, cu toate avantajele de īntretinere si usurinta īn distributie a aplicatiei.
Ultima definitie care poate fi data procedurilor stocate este ca ele definesc porti de acces la date. Ca orice poarta, ea poate controla cine si la ce are acces. Controlul accesului se face pe baza utilizatorilor din baza de date, motiv pentru care este mult mai simplu sa se gestioneze o astfel de aplicatie, comparativ cu solutia īn care utilizatorul trebuie sa se autentifice cu serverul de aplicatii, apoi cu serverul bazei de date.
Din definitiile de mai sus se pot desprinde deja unele avantaje ale procedurilor stocate Java, dar le vom discuta separat, īn cadrul sectiunii ...
Avantajele procedurilor stocate Java
Problema de care se plāng multi utilizatori ai limbajului Java este slaba performanta. Toti acestia sunt invitati sa citeasca paragrafele urmatoare, pentru ca ele releva masurile pe care Oracle le-a luat pentru a crea si oferi avantajul major al folosirii procedurilor stocate Java: īnalta performanta.
Dupa toate aceste avantaje, mai trebuie clarificata o mica nedumerire: de ce Java si nu PL/SQL? Articolul de fata nu doreste sa minimizeze importanta PL/SQL. Merita mentionat īn acest sens produsul WebDB, tot al firmei Oracle, care permite gestiunea unei baze de date si crearea unui sit WWW populat cu informatii dintr-o baza de date folosind ca instrument de dezvoltare un program de navigare obisnuit. Desigur, greul este dus de procedurile stocate, scrise integral īn PL/SQL. Ceea ce doreste īnsa sa sublinieze acest articol sunt caracteristicile procedurilor stocate Java, astfel īncāt un proiectant sau dezvoltator sa cunoasca toate posibilitatile ce i se ofera.
Avantajul PL/SQL este o corespondenta perfecta īntre tipurile de date din baza si cele ale limbajului, zona īn care Java are multe conversii de facut. Din acest motiv, recomandarea firmei Oracle este de a se scrie proceduri PL/SQL pentru sarcini de manipulare intensiva a datelor, procedurile Java fiind destinate zonei īn care se efectueaza calcule intense combinate cu accesuri rare la informatii.
Masina virtuala Java din Oracle 8i
Masina virtuala Java implementata īn Oracle 8i, cunoscuta sub numele de Aurora, ofera un mediu de executie conform cu JDK 1.1.6. Evident, masina virtuala nu are implementata partea de grafica, dar īn rest ofera un mediu complet Java. Aurora este proiectata sa ruleze īn acelasi spatiu de adrese cu nucleul bazei de date, motiv pentru care consumul de memorie este redus, iar performantele ridicate.
Trebuie remarcat ca codul poate fi lansat īn
executie atāt prin intermediul unor apeluri din SQL, PL/SQL sau alt cod
Java, cāt si prin intermediul unor apeluri IIOP, īn cazul obiectelor
Java/CORBA care ruleaza īn cadrul serverului. Codul
compilat joaca o mare importanta īn
Gestionarul de biblioteci este cel care īncarca sursele, clasele sau fisierele resursa Java īn baza de date, ca rezultat al comenzii SQL CREATE JAVA. Nu este posibila accesarea directa a acestor obiecte; doar masina virtuala poate sa le foloseasca.
Gestionarul de memorie este cel care se ocupa de colectarea memoriei disponibile. Mecanismul de colectare se bazeaza pe tehnici de alocare a memoriei adaptate la timpul de viata a obiectelor. Astfel, obiectele care supravietuiesc īn afara scopului functiei care le-a creat sunt migrate īn alte zone de memorie. Pentru reducerea necesarului de memorie, gestionarul de memorie partajeaza starea constanta a obiectelor, cum ar fi definitiile de clase si variabilele statice finale.
Compilatorul Aurora are rolul de a compila sursele care sunt introduse īn baza de date prin intermediul unei fraze CREATE JAVA SOURCE. Rezultatul este un bytecode compatibil JDK.
Interpretorul este si el compatibil JDK 1.1.6 si se executa pe componenta MultiThreaded Server (MTS) a serverului Oracle, cea care gestioneaza sesiunile si planifica executia programelor Java. Sistemul de asistenta la executie (runtime) permite apelul de metode native si comunicatii din interior sau exterior, dar aceste actiuni se pot executa doar daca utilizatorul are privilegiile corespunzatoare.
Īncarcatorul de clase este cel care localizeaza, īncarca si initializeaza clasele Java stocate īn baza de date. El citeste clasa, si apoi genereaza structurile de date de care este nevoie pentru executie. Constantele sunt plasate, pentru eficienta, īntr-o zona de memorie partajata cu alte sesiuni. De asemenea, el invoca compilatorul de Java automat, daca se constata ca este nevoie de recompilarea surselor si sursele sunt disponibile. Verificatorul este cel care verifica daca bytecode-ul Java respecta regulile si formatul predefinit, īmpiedicānd astfel violarea restrictiilor de acces. Verificatorul este parte integrata īn sistemul de securitate, asigurat atāt de securitatea Java cāt si de cea a bazei de date Oracle.
Din punct de vedere al performantelor, scopurile principale ale proiectantilor Aurora a fost scalabilitatea si executia rapida pentru cod care ruleaza mult timp. Asadar, orice test aplicat acestei masini virtuale trebuie sa aiba īn vedere si aceste aspecte particulare. Pentru moment, JVM clasica, de la Sun, este mai rapida pentru activitatile foarte scurte (de exemplu, proceduri stocate care efectueaza calcule de tipul 2+2), dar devine mai slaba īn performante o data cu timpul de rulare. De asemenea, trebuie tinut cont si de faptul ca scopul acestei implementari este de a sustine, īn final, cāt mai multe cereri simultan, iar aici testele au aratat ca Aurora este de cel putin 4 ori mai scalabila decāt orice alta masina virtuala. Pentru cei pe care timpul de executie īi nemultumeste, Oracle pune la dispozitie JServer Accelerator, care realizeaza translatarea codului Java īn cod C ce poate fi compilat pe masina server si executat ulterior prin intermediul unei biblioteci partajate care este īncarcata de Aurora. O alta crestere de viteza este data de furnizarea, alaturi de clasele de sistem, a unor packag-uri ORB si JDBC ce au asociate versiuni compilate nativ.
Evident, partea de legatura cu baza de date este de īnalta calitate. Driverul JDBC ruleaza chiar īn interiorul serverului, oferind cel mai rapid acces posibil la date. El este conform cu specificatiile JDBC 1.22 de la Sun si suporta tipurile specifice bazelor de date Oracle, seturi de caractere nationale si apelul de proceduri stocate. Conformitatea cu standardul JDBC face posibila punerea īn executie a aceluiasi cod atāt īn baza de date, cāt si īntr-un applet sau aplicatie la client. Īn mod similar, la nivelul serverului exista si o implementare de SQLJ, care permite integrarea mult mai usoara a codului SQL cu cel Java.
Cāteva cuvinte si despre restrictiile care sunt impuse codului care se executa pe Aurora JVM, deci si procedurilor stocate. Īn primul rānd, se permite folosirea tuturor claselor din partea de grafica, cu conditia de a nu se īncerca materializarea unei ferestre.
Programele cu mai multe fire de executie se executa pe server fara modificari, dar ele trebuie sa tina cont de faptul ca implementarea este cu fire de executie gestionate īn spatiul utilizator. Cu alte cuvinte, īn mediul serverului firele de executie nu sporesc concurenta, pentru ca acest lucru este guvernat de catre MTS si metode de optimizare specifice serverului. Asadar, diferentele importante sunt ca firele de executie pe server:
Practic, īn terminologia Oracle, mutithreading se refera la sesiuni utilizator concurente, si nu la mai multe fire de executie īn sensul Java. Planificarea executiei Java pentru atingerea scopului de tratare a cāt mai multi utilizatori simultan este realizata de sistemul de gestiune, si nu de catre masina virtuala Aurora.
Contextul de rulare al procedurilor stocate
Īnainte de prezentarea modului īn care se face dezvoltarea unei proceduri stocate, este utila mentionarea locurilor īn care pot fi īntālnite aceste proceduri, sau asa numitele contexte de rulare.
Prima utilizare este cea clasica, data chiar de nume, si anume proceduri (sau functii) apelabile explicit din SQL sau PL/SQL. Ele pot primi parametri, iar functiile pot fi apelate si din fraze SQL de manipulare a datelor (DML), cum ar fi INSERT, UPDATE, DELETE si SELECT.
A doua utilizare este de componenta logica īn cadrul unui trigger. Īn acest caz, procedura stocata este asociata cu o tabela sau o vedere anume. SGBD-ul declanseaza automat triggerul atunci cānd o anumita operatie DML modifica tabela sau vederea. Declansarea triggerului se traduce printr-un apel CALL al procedurii stocate. Rolul principal al triggerelor este de a completa mecanismele oferite de baza de date, prin impunerea unor reguli de afaceri mai complexe, cum ar fi prevenirea tranzactiilor invalide, īnregistrarea si auditul evenimentelor.
Cea de-a treia utilizare este cea de metoda pentru obiectele stocate īn baza de date si create cu fraza CREATE OBJECT. Īn acest context, procedura stocata devine o metoda a unui obiect si ajuta, o data īn plus, la extinderea lucrului cu obiectele din Oracle8.
Dezvoltarea unei proceduri stocate
Primul pas pe drumul crearii si utilizarii unei proceduri stocate este cel de dezvoltare. Pentru dezvoltare, se recomanda folosirea unui mediu vizual, care sa stie sa automatizeze si unii din pasii urmatori. Cel mai potrivit este Oracle JDeveloper, fiind foarte bine integrat cu restul gamei de produse Oracle, oferind si multe utilitare de control.
Procedura stocata din baza de date se obtine dintr-o metoda a unei clase Java. Atunci cānd se apeleaza o procedura stocata nu se creeaza un obiect; clasa din care face parte metoda transformata īn procedura stocata nu este instantiata. Implicatiile acestui fapt sunt ca:
Alte diferente fata de o clasa normala sunt la modul de transmitere al parametrilor. O procedura stocata poate avea parametri din intrare si/sau de iesire. Variabilele de iesire sunt declarate ca vectori. Acest lucru este necesar pentru a putea pasa parametri de iesire ca referinte la obiecte, si nu ca variabile primitive.
Ultima caracteristica este folosirea unei conexiuni JDBC speciale, cea implicita pentru driverul JDBC din baza de date. Modul de obtinere al acestei conexiuni poate fi remarcat īn codul sursa al exemplului de procedura stocata. Driverul JDBC din baza de date nu suporta modul de lucru autocommit, deci este necesar ca utilizatorul sa gestioneze explicit tranzactiile.
Pentru ilustrarea fazelor prin care trebuie trecut pentru a utiliza o procedura stocata, se va considera cazul unei proceduri care face inserarea unui obiect īntr-o magazie. Metoda care va fi transformata īn procedura stocata se numeste addStockItem, iar clasa din care face parte este StockManager.
Īncarcarea unei proceduri stocate
Cel de-al doilea pas spre utilizarea finala a unei proceduri stocate este īncarcarea procedurii stocate īn baza de date. Īn acest scop, Oracle 8i ofera un utilitar numit loadjava, care permite automatizarea procesului de īncarcare. JDeveloper, de la versiunea 2.0 īn sus, permite ca o optiune de distributie si punere īn exploatare a unei clase si īncarcarea de proceduri stocate. La momentul īncarcarii trebuie definite toate metodele care se doresc a fi transformate īn proceduri stocate, pentru ca pentru acestea trebuie generate specificatori de apel (call specs) īn dictionarul de date Oracle. Aceasta activitate poarta numele de publishing (publicare). Succesiunea de evenimente si entitatile implicate īn cele doua activitati sunt ilustrate īn figurile: "Modul de lucru al utilitarului loadjava" si "Utilizarea specificatorilor de apel".
Trebuie facuta o distinctie clara īntre un īnvelis SQL sau PL/SQL si un specificator de apel. Īn primul caz, se creeaza o procedura PL/SQL care apeleaza, din interior, procedura stocata Java. Īn cel de-al doilea caz, se genereaza doar o declaratie de procedura, pe baza careia procedura poate fi identificata si īsi poate primi parametri. Rolul specificatorului de apel este deci de a permite asocierea numelor de metode Java, a tipurilor parametrilor si a rezultatelor cu echivalentele din SQL.
Un exemplu de rulare a utilitarului loadjava, īn care cerem ca sa se produca compilarea codului si rezolvarea referintele externe din clase (optiunea -v) si conectarea la baza de date prin driverului JDBC de tip thin (optiunea -t), este:
Crearea package-ului īn care sta procedura stocata si declararea ei se face prin urmatoarele doua comenzi SQL, generate automat daca se foloseste asistentul de distributie (Deployment Wizard) din JDeveloper.
Verificarea cu SQL*Plus a functionarii procedurii stocate se poate face prin simpla comanda:
CALL stock_manager.add_stock_item(2000, "speakers", 10);
Utilizarea unei proceduri stocate
Daca toti pasii au fost parcursi corect, procedura este deja īn baza de date si deja putem sa o folosim din programe. De exemplu, o secventa de cod Java/SQLJ care sa faca apel la o procedura stocata este:
Aspecte de securitate
Īn mod normal, procedurile stocate Java sunt executate cu privilegiile celui care invoca procedura. Toate obiectele care nu sunt calificate sunt cautate īn schema celui care invoca procedura. Pentru a schimba acest comportament implicit, se poate utiliza un parametru (definer) al utilitarului loadjava.
Folosirea unei proceduri ce se executa cu drepturile celui care o invoca (invoker rights) este utila pentru crearea unui depozit central de proceduri stocate. De exemplu, o firma cu mai multe sucursale poate sa plaseze o procedura de analiza pe un server central. Fiecare filiala, cānd va vrea sa faca analiza, o va face pe propria baza de date. Daca se doreste ca procedura centralizata sa faca modificari pe baza centrala (de exemplu auditul analizelor), atunci procedura de analiza va trebui sa apeleze alta procedura, de īnregistrare, care sa se execute cu drepturile celui care a definit-o. Cele doua cazuri sunt ilustrate īn figura "Metodele de executie a codului Java".
Executia unei proceduri se poate face doar daca utilizatorul are drept de executie. Un utilizator poate capata drepturi de modificare a unei tabele, prin executia unei proceduri stocate, chiar daca el nu are drepturi de modificare a tabelei.
Īn plus, nu trebuie uitate si restrictiile impuse de masina virtuala. Astfel, o procedura stocata nu are acces la discul serverului si nu poate comunica īn retea decāt daca se specifica explicit anumite privilegii.
Concluzii
Caracteristicile platformei Java o fac ideala pentru programarea la nivelul serverului bazei de date, iar optimizarile specifice Oracle 8i creeaza un mediu de productie pentru aplicatiile Java. Java permite asamblarea aplicatiilor folosind componente software prefabricate (off-the-shelf). Siguranta tipurilor si gestiunea automata a memoriei permit integrarea strānsa cu SGBDR-urile moderne. Īn plus, Java permite distribuirea transparenta a componentelor aplicatiilor īn retea.
Astfel, Java si SGBDR permit asamblarea rapida a aplicatiilor bazate pe retea si componente software, aplicatii care pot evolua lin pe masura ce se schimba cerintele afacerii. Codul aplicatiei si depozitul de date poate fi mutat de pe calculatorul de pe birou īn cadrul unei retele inteligente sau pe servere de sprijin pentru arhitectura NCA (Network Computing Architecture). Ceea ce este cel mai important este ca aceste aplicatii pot fi accesate de la orice program de navigare.
Performantele implementarii Oracle de masina virtuala din cadrul serverului Oracle 8i cresc atractivitatea dezvoltarii de aplicatii Java. Astfel, dupa cucerirea sectorului aplicatiilor client, Java trece la atac si īn domeniul bazelor de date. Iar surprizele nu se vor opri aici: urmatoarea versiune de Oracle 8i (8.1.6) va oferi suport pentru alte tipuri de componente Java, pe aceeasi masina virtuala. JSP (Java Server Pages), si servlet-urile vor fi tehnologiile Java implementate alaturi de EJB, CORBA, proceduri stocate Java.
Tehnologiile care vor modela viitorul apropiat sunt cele legate de portabilitate, standardizare si universalitate. Java este solutia care īndeplineste aceste conditii pentru continut executabil, asa cum UML (Unified Modelling Language) si XML (eXtensible Markup Language) o fac pentru modelarea sistemelor, respectiv reprezentarea datelor. Combinatia dintre cele trei forte nu poate duce decāt la lucruri bune, iar firmele puternice de software, printre care si Oracle, pregatesc surprize placute prin produse ce se bazeaza pe toate aceste tehnologii. Integrarea īn produsele de dezvoltare a acestor tehnologii permite dezvoltarea īn timp mai scurt a unui software de calitate si deschis interactiunilor cu alte sisteme.
Bazele de date si mediile de dezvoltare asociate sunt deja pregatite sa sprijine aplicatii bazate pe tehnologiile Internet. Sunteti pregatiti sa le exploatati? Sper ca vocea din reclama a maestrului stefan Iordache sa vorbeasca si īn numele dumneavoastra ...
|