Sunteți pe pagina 1din 42

Capitolul VIII

Integrarea bazelor de date folosind JDBC

Mediul Java Enterprise fiind orientat–obiect, independent arhitectural care suportă încărcarea
dinanmică ă aplicaţiilor componenete în sisteme distribuite, devine unul din cele mai
importante tehnici utilizate pentru tehnologiă hardware şi software în sistemele distribuite.
Java Enterprise permite creareă unor sisteme protejate realizate pruin diferite instrumenete,
unul dintre ele fiind accesul la diferite baze de date relaţionale, de diverse tipuri folosind
Java Database Conectivity (JDBC).

8. Integrarea bazelor de date cu Java Enterprise prin JDBC


8.1. Concepte

Datorită ajutorului JDBC Java Enterprise oferă posibilitatea de a integra popularele DBMS –
uri şi datorită naturii ei orientate catre reţea fac din Java Enterprise un mediu propice pentru
programarea client–server. Faţă de facilităţile puse la dispoziţie de C ++ , Java Enterprise –
combinate cu JDBC (Java Database Conectivity)- oferă noi capacitati de comunicare cu
bazele de date într-un sistem similar cu cel oferit de aplicaţiile din C şi C++. Datorită faptului
că Java E este un limbaj independent de platformă, putând rula în orice sistem, majoritatea
organizaţiilor economice din întreaga lume îl utilizează.
Orientarea catre reţea a lui Java E, face că acest mediu de programare să fie ideal pentru
programareă client/ server, mai ales în aceste momente în care capacităţile de integrare cu
Sistemul de Management al Bazelor de Date (DBMS) este din ce în ce mai dezvoltat, deşi
uneori s-au pus sub semnul întrebării validitatea utilizării mediului Java Enterprise pentru
dezvoltarea unor aplicaţii formale. Multi utilizatori fac confuzie între natura Java E şi
posibilitatea de a crea mici aplett-uri şi aplicaţii pentru pagini Web.
Majoritatea celor care achizitionează soft-ul pentru Java E văd în el capacitateă acestuia de a
fi portabil şi securitatea pe care o oferă aplicaţiilor dezvoltate în Java E, securitatea fiind
vazută că cea mai importantă caracteristică a unui program. Java E, oferă noi capacităţi de
integrare a bazelor de date prin sisteme similare cu cele din C şi C++ şi în plus, programatorii
în Java E nu au reuşit încă să folosească la maximum capacitatea Java E ca un limbaj liber
de platformă.
Vânzatorii cei mai mari de baze de date că Oracle, IBM, Sysbase, SAS şi Borland au verificat
foarte bine inainte de a vinde Java EE metodologia prin care Java EE a integrat bazele de date
(metodologia de integrare Java EE - DBMS). De asemenea marii dezvoltatori de softuri, că
Gupta, Rogue Wave, Symantec au devenit foarte interesaţi de această nouă piaţă pe care o
oferă Java EE.

8.2. JDBC
Primă facilitate de integrare a bazelor de date cu Java EE a aparut într-o specificaţie numită
Java database Conectivity (JDBC) Aplicaţion Programming Interface (API). Aceasta a fost
creată cu ajutorul facilităţilor oferite de DBMS şi cu ajutorul instrumentelor pentru
dezvoltarea bazelor de date oferite de majoritatea celor care vindeau programe orientate catre
manipulareă acestor baze de date, fie că erau baze de date distribuite fie că era vorba de baze
de date relaţionale. Facilitatea oferită de Java EE vine să umple golul lasat de faptul că nu s-
au incercat foarte multe variante de realizare a conenctivităţii bazelor de date cu alte soft-uri,
atât din punct de vedere al limbajului propriu-zis (ca şi cod) cât şi din punct de vedere a
interfeţei utilizator.
Un program Java care utilizează JDBC este structurat pe două straturi:

1
Primul strat este orientat spre aplicaţia Java şi se numeşte Driver manager în esenţă un obiect
ce face referire la aspecte legate direct de aplicaţie;
Al doilea strat este orientat spre SGBD şi necesită drivere specifice bazelor de date la care
aplicaţia strebuie să aibă acces. JDBC permite aplicaţiilor Java să acceseze mai multe tipuri de
baze de date:

Aplicaţia Java
Figura 8.1.
Manipularea BD cu
JDBC JDBC Driver manager

Driver Oracle Driver Access Driver Informix

BD BD BD
Oracle Oracle Oracle

JDBC crează o interfaţă pe diferite nivele prin care se realizează comunicarea cu bazele de
date într-un mod uniform, similar ca şi concept cu componenetele oferite de catre Microsoft’s
Open Database Conectivity (ODBC), care au devenit standarde pentru calculatoarele
personale şi Lan-uri. Standardul JDBC se bazează pe X/Open SQL Call Level Interface, care
stă şi la bază standardului pentru ODBC, unul dintre motivele pentru care JDBC s-a dezvoltat
atat de repede.
Clasele obiect care fac posibilă deschiderea acestor tranzacţii cu bazele de date sunt scrise în
totalitate cu Java pentru a permite interacţiune mai mare decat una obţinută în cazul în care se
scriau în limbajul C, urmând că apoi să fie folosite că funcţii apelate din Java, lucru care ar fi
trebuit să fie facut în cazul ODBC. în acest fel se poate menţine securitatea, robustetea şi
portabilitateă care fac din Java EE un mediu de programare asă de incitant. Oricum pentru a
se promovă şi pentru a se mentine compatibilitatea, JDBC poate fi implementant peste ODBC
şi alte interfeţe SQL.
JDBC este format din două părţi principale: JDBC API care oferă posibilitatea de a se realiza
managmentul comunicatiei pentru JDBC, şi implementări pentru JDBC Manager–to–
Driver, manager care realizează controlul comunicarii cu multiple drivere de diferite tipuri
prin implementarea unei interfeţe directe intre driverele de interfaţă oferite de Java EE şi
cele oferite de ODBC.
In pachetul java.sql apar şi o serie de clase şi interfeţe ce permit accesul şi
manipularea bazelor de date, grupate în 8 interfeţe, (figura 8.2.) constând din:
 java.sql.Environment – permite crearea unei noi conexiuni pentru o bază de date;
 java.sql.Connection – specifică structură datelor pentru conexiune;
 java.sql.Statement – clasă container pentru comenzi SQL ;
 java.sql.ResultSet – asigură controlul accesului la rezultatele comenzilor.
 java.sql.ResultSetMetaData- se utilizează pentru a afla informaţii despre tipurile sau
proprietăţile coloanelor din ResultSet;
 java.sql.CallableStatement – permite executarea procedurilor stocate în baza de
date;

2
 java.sql.DatabaseMetaData – permite returnarea informaţiilor din baza de date,
număruld e tabele ce compun baza de date, structura tabelelor din baza de date,nuărul
de câmpun ce compun o tabelă,etc.;
 java.sql.Driver – cadrul JDBC penztru conexiuni multiple. Orice diver oferă o clasă
ce implementează această interfaţă. Când o aplicaţie facecererea de conectare la o
bază de date, clasa DriverManager interoghează fiecare driver dacă poate sau nu să
realizeze conexiunea cu sursa de date. Interogarea este posibilă doar dacă acest driver
poate implementa metode din interfaţa Driver;
 java.sql.PreparedStatement – asigură stocarea comenzilor SQL într-un obiect de tip
PreparedStatement, care poate fi utilizat ulterior pentru executarea respectivului
enunţ, oferind o eficienţă crescută aplicaţiilor.
DriverManager
Figura 8.2.
Interfeţe din
biblioteca JDBC
Connection

Statement PreparedStatement CallableStatement

ResultSet ResultSet ResultSet

Diverul pentru JDBC API este continut în java.sql.Driver. Fiecare driver trebuie să ofere
implementările clasei la toate clasele virtuale: java.sql.Connection, java.sql.Statement,
java.sql.PreparedStatement, java.sql.CallableStatement, şi java.sql.ResultSet. Clasele virtuale
descriu API dar sunt specifice modului în care lucrează fiecare bază de date. Puntea dintre
JDBC- ODBC permite traduceri ale apelurilor JDBC în apeluri care pot fi întelese de către
clientul ODBC la nivelul limbajul C. Rolul punţii este de a izola apelurile tipice pentru C
catre o zonă controlată menţinându-se în acelaşi timp compatibilitatea cu baze de date non-
JDBC.

8.3. JDBC în Internet

Sun sustine ideea folosirii comerciale a reţelelor mari cum ar fi Internetul, iar furnizorii de
baze de date recunosc importantă acestei idei iar o primă problemă pentru JDBC a fost cum
va funcţiona pe Internet. Multe din problemele catre privesc securitatea sunt deja rezolvate în
Java, dar alte probleme cum ar fi accesareă unor baze de date de pe Internet trebuie avute în
vedere. Pentru acest motiv JDBC împrumută sintaxă Uniform Resource Locator (URL)
pentru adresareă unică şi globală a bazelor de date. O schemă comună de URL cum ar fi
http://www.javaworld.com, indică o adresă WWW iar JDBC urmăreşte o sintaxă similară. O
adresă completă url este formată din câteva elemente esenţiale:
http://host.domain.com:80/directory1/directory2/filename
Elementele unei URL
 http - schema URL, protocolul Hypertext transfer

3
 host.domain.com- este un nume de host unic în Internet asignat fiecarui calculator.
 80 - portul de Internet al hostului la care este localizat serviciul, portul 80 fiind portul
implicit la care serviciul http este localizat.
 directory1/directory2/ - setul subliniază în iererahie unde este situat filename
 filename - indică datele cautate.
Structură URL a JDBC este similară, ca şi în exemplul dat:
jdbc:odbc://host.domain.com:400/databasefile
In plus fată de schemă principală JDBC această structură include şi un subprotocol pentru
ODBC, care indică modul cum Managerul JDBC va accesa bază de date. In acest caz baza de
date va fi accesată pe bază unui punţii JDBC-ODBC celelalte componente fiind similare
URL-ului, incluzând numele hostului, portul şi locatia şi numele bazei de date.
Funcţionarea asincronă care este uneori inclusă în alte API ale bazelor de date ca interogări
SQL specifice şi mecanisme adiţionale este realizată de către natura multifir a Java EE.
Programatorul poate uşor crea fire de execuţie separate pentru fiecare din activităţile
asincrone. Oricum toate operaţiile care folosesc clasele Java.sql trebuie scrise ca şi cod
multifir sigur, chiar dacă obiectele accesează aceste operaţii prin fire unice. Acest API
furnizează proceduri de realizare a tranzacţiilor. Fiecare tranzacţie începe cu o metodă
beginTransaction şi poate fi efectuată sau se poate reanuntă la ea. Odată ce a fost efectuată
sau s-a renuntat la ea, toate cererile deschise pentru această tranzacţie vor fi închise.
SQL a fost de multe ori extins pentru a furniza funcţionalitatea lipsă din specificaţile standard
originale. Pentru a se acomodă la aceste schimbări JDBC oferă un mecanism pentru
extinderea cererilor SQL, similar cu cele disponibile în ODBC folosind sintaxa:
{keyword ... parameters ...}
Pentru a compensa şi mai mult trăsăturile pentru baze de date specifice furnizorii pot să
extindă clasesele de interogare standard pentru a se mula pe propriul design deşi clasele
standard trebuie integrate de toate bazele de date pentru a permite legatură cu JDBC.
Tipuri de date permise în JDBC sunt în strânsă corespondenţă cu tipurile SQL, astfel:

Tip SQL - Java Type Description


CHAR - StringSingle Character
VARCHAR - StringVariable length string of characters
LONGVARCHAR - java.io.InputStream Very long (multi-megabyte) strings
NUMERIC - java.sql.Numeric Absolute precision fixed-point values
DECIMAL - java.sql.Numeric Absolute precision Decimal value
BIT - Boolean Single bit/binary value (on or off)
TINYINT - byte 8-bit integer
SMALLINT- short 16-bit integer
INTEGER -int signed 32-bit integer
BIGINT - long signed 64-bit integer
REAL - float Floating-point value
FLOAT - float Floating-point value
DOUBLE - double Large floating-point value
BINARY - byte[] Array of binary values
VARBINARY - byte[] Variable length array of binary values
LONGVARBINARY - java.io.InputStream Very large (multi-megabyte) array of binary
values
DATE - java.sql.Date Date value
TIME - java.sql.Time Time value (GMT)
TIMESTAMP - java.sql.Timestamp Time value with additional nanosecond field To sum up

4
JDBC urmăreşte o specificaţie stabilită şi implementarea pentru comunicaţiile neutre de la
aplicaţii. Solutia cu punţi pentru sistemele curente ODBC permite utilizatorilor să menţină
compatibilitatea cu sistemele mai vechi, către s-ar putea să nu aibă corespondent JDBC.
Furnizorii de top lucrează pentru a realiza componente JDBC pentru bazele lor de date chiar
dacă JDBC este încă în fază de germinare. Orice rezultate ale acestei munci vor putea fi
văzute doar când furnizorii vor fi pregătiţi, ceea ce reprezintă o împiedicare implicită a
procesului There de dezvoltare a mediului Java. Competiţia declanşată de Microsoft prin
ActiveX (cunoscute şi că OLE Control Extensions), Visual Basic şi .NET exprimă presiunea
Microsoft pentru realizareă unei lumii a apleturilor portabilă şi on line. Problema cu
independenţă de platformă este clară şi evidentă în această soluţie. Componente cum ar fi
JDBC pot fi printre factorii de decizie care să facă deciziile pentru firmele de software care se
confruntă cu asemeneă probleme.

8.4. JDBCTM

JDBCTM este JavaTM API pentru execuţia interogărilor SQL şi constă dintr-un set de clase şi
interfeţe scrise în limbajul de programare Java. JDBC oferă un standard API pentru
dezvoltareă uneltelor / bazelor de date şi face posibilă scriereă unor aplicaţii pentru bazele de
date utilizandu-se o API Java pură. Utilizand, JDBC este uşor să se transmite interogările
SQL către bazele de date virtuale şi relaţionale deci nu este necesară scrierea unui program
pentru accesarea unei baze de date Sysbase, altul pentru accesarea unei baze de date Oracle,
altul pentru accesarea unei baze de date Informix, etc ci doar un singur program, folosind
JDBC API care va fi capabil să trimită interogările SQL celei mai apropiate baze de date. Cu
ajutorul unei aplicaţii scrise cu ajutorul Java Enterprise Edition, nu constituie o problemă
portabilitatea aplicaţiilor pe diferite platforme deoarece combinaţia dintre Java Enterprise
Edition şi JDBC oferă posibilitatea programatorului de a scrie codul şi de a-l folosi în orice
moment, pe orice tip de platformă.
Java Enterprise Edition fiind un limbaj roobust, uşor de utilizat şi de înteles, care se poate
downlada direct de pe Internet, este un excelent limbaj de bază pentru programarea bazelor de
date. Acesta solicită doar un limbaj de comunicare cu diferitele tipuri de baze de date, realizat
prin intermediul JDBC care extinde facilităţi Java. De exemplu, cu Java şi JDBC API, este
posibilă publicarea unei pagini Web care conţine un applet în care sunt incluse informaţii
obţinute de la o bază de date aflată la distanţă. O organizaţie poate să utilizeze JDBC pentru
a-şi conecta toţi angajatii ei - în ciuda faptului că aceştia utilizează diverse maşini: Windows,
Machintosh şi Unix - la una sau mai multe baze de date, prin intermediul intranet-ului.
Datorită faptului că toti mai multi programatori au început să folosească Java Enterprise
Edition şi JDBC pentru integrarea bazelor de date s-a impus necesitatea accesului facil la
bazele de date. Managerilor aflati la nivelul MIS, agrează combinaţia Java Enterprise Edition
şi JDBC, deoarece le oferă posibilitatea regăsiri rapide şi cu costuri scăzute a informaţiilor
economice aflate în diverse puncte. Acesteă le oferă posibilitatea oamenilor de afaceri să-şi
utilizeze în continuare bazele de date de care dispun deja şi în acelaşi timp le oferă capacitatea
de a-şi extrage informatiile uşor, chiar dacă bazele de date se află într-un alt sistem de
management al acestor baze. Dezvoltarea noilor aplicaţii se face într-un timp foarte scurt
deoarece instalarea şi variantele de control a versiunii au fost simplificate foarte mult. Un
programator poate scrie o aplicaţie sau o poate adapta odată ce a fost scrisă, să o pună pe
server, şi toată lumea vă avea acces la ultimă versiune. Pentru informaţiile referitoare la
serviciile de vânzare, Java EE şi JDBC oferă o metodă mult mai bună de a adaptă
informaţiile externe referitoare la clienţi.
In esenţă JDBC face posibilă realizarea comunicării cu o bază de date prin: stabilirea unei
conexiuni cu baza de date, trimiterea interogărilor SQL, procesarea rezultatelor.

5
Un cod care oferă un exemplu de bază pentru realizarea acestor etape:

Connection con = DriverManager.getConnection (“jdbc:odbc:wombat", "login",


"password");
Statement stmt = con.createStaţement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
int x = getInt("a");
String s = getString("b");
float f = getFloat("c");
}
JDBC este “interfaţa de nivel inferior” utilizată pentru a invoca direct interogări SQL şi se
lucrează cu această componentă realizând mai uşor conexiunea cu bazele de date decat în alte
API, dar în acelaşi timp a fost creat pentru a constitui o bază pentru alte interfeţe de nivel
superior. Intefeţele “user-friendly” , utilizează API mult mai uşor de înteles şi conveniente,
decât dacă ar fi fost traduse într-o interfaţă de nivel inferior ca şi JDBC. JDBC cere ca
interogările SQL să fie trimise ca un şir în cadrul metodelor Java. Un preprocesor de
traducere a SQL permite programatorului să combine interogările tip SQL direct cu
declaraţiile Java. Spre exemplu, o variabilă java poate fi utilizată într-o înterogare SQL pentru
a primi sau pentru a fi bază unei valori SQL. Preprocesorul SQL traduce apoi această mixtură
Java / SQL în limbaj Java prin Intermediul JDBC.

Java Soft şi altii şi-au anunţat intenţia de a mapa în mod direct tabelel bazelor de date
relaţionale în clase Java. In această mapare “obiect/relaţie” fiecare linie a tabelului devine o
instanţă a clasei, şi fiecare valoare a unei coloane corespunde unui atribut al acestei
instanţieri. Programatorii pot apoi să opereze direct asupră obiectelor Java, interogarea SQL
cheamă şi stochează datele generate în spatele programului. Cum interesul pentru JDBC a
început să crească, multi producători soft au încercat să ofere unele instrumente care să facă
JDBC mai uşor de utilizat.

8.5. JDBC versus ODBC şi alte platforme API

In acest moment Microsoft ODBC (Open DataBase Conenctivity) API este probabil ceă mai
raspândită metodă de programare a interfeţelor de accesare a bazelor de date care oferă
capacitatea de conecta aproape toate bazele de date, de pe aproape orice platformă. Se pune
problema de ce nu se utilizează numai ODBC pentru Java Enterprise Edition. Răspunsul este
că deşi se poate utiliza ODBC cu java conectarea la bazele de date este mai uşor de realizat
dacă se utilizează puntea ODBC - JDBC.
ODBC nu este recomandată pentru utilizarea directă cu Java întru-cât utilizează o interfaţă
C iar apelurile din Java catre nativul capitol nu oferă o securitate foarte ridicată, are probleme
în ceea ce priveste implementarea, robustetea şi portabilitatea automată pe alte platforme. De
fapt JDBC a fost creat tocmai pentru a rezolvă problemele ODBC şi pentru a permite
realizarea mai facilă a altor operaţii.

8.6. Integrarea SQL


8.6.1. Metode de integrare

Structured Query Language (SQL) este limbajul standard pentru accesarea bazelor de date
realationale deşi nu este la oră actuală un standard aşa cum ar trebui să fie. Una din probleme
sunt tipurile de date folosite de diferite SGBD-uri, care uneori variază şi variaţiile pot fi

6
semnificative. JDBC se ocupă cu definireă unui set de identificatori de tip generici în clasa
java.sql.

Un alt aspect de dificultate pentru SQL este faptul că cu toate că majoritatea SGBD-urilor
folosesc o formă standard de SQL pentru functionarea standard, nu sunt conforme cu sintaxa
şi semantica standard pentru SQL, mai recentă pentru mai multe funcţionalităţi. De exmplu nu
toate bazele de date suportă proceduri stocate şi outer join, şi cele care o fac nu sunt
consistente intre ele. Se speră că aceă parte a SQL care este în realitate un standard se va
extinde pentru a include mult mai multe functionalităţi dar în acelasi timp API –ul JDBC
trebuie să suporte SQL aşa cum este.
1. O metodă prin care JDBC tratează aceast problemă este prin permiterea oricărei interogări
sub formă de şir de caractere să fie transmisă unui driver de SGBD. Această înseamnă că o
aplicaţie este liberă să folosească atât funcţionalitate JDBC, dar apare riscul apariţiei unor
erori pe unele SGBD-uri. De fapt o aplicaţie care conţine interogări nu trebuie să fie neaparat
SQL ci poate fi şi o derivaţie a SQL destinată pentru SGBD-uri specifice cum sunt interogări
de document sau imagine.
2. O a două metodă prin care JDBC lucrează cu probleme de integrare ă SQL este prin
furnizareă unei clauze de ieşire asemanătoare ODBC. Sintaxa de ieşire furnizează un standard
JDBC, pentru mai multe domenii în care SQL nu poate actiona ca un standard.
3. Pentru aplicaţii complexe, JDBC realizează integrarea SQL în al treilea mod şi furnizează
informaţii descriptive despre SGBD prin interfaţa DatabaseMetaData astfel incât aplicaţiile
să se poată adapta necesităţilor şi facilităţilor fiecărui SGBD. Utilizatorii finali obişnuiti nu işi
pun probleme despre metadatele utilizate.

Deoarce JDBC este folosit că bază pentru dezvoltarea unor instrumente de acces la baze de
date are de asemenea de rezolvat şi problema conformităţii cu orice aplicaţii ce sunt realizate
în ele. Realizarea JDBC Compliant(TM) a fost creată pentru a realiza un nivel mai înalt de
funcţionalitate JDBC pentru utilizatori. Pentru a folosi această variantă un driver trebuie să
suporte măcar ANSI SQL-2 Entry Level. Dezvoltatorii de drivere pot realiza acest deziderat
prin testareă componentelor care vin cu JDBC.

Conectabilitatea bazelor de date Java (JDBC)

S-a estimat că jumatate din software-uri includ operatii de tip client server. JDBC este
conceput a fi independent de platforma , astfel nu trebuie să ne preocupe baza de date pe care
o folosim în timp ce programam. Apelul la metoda pe care il facem, corespunde cu operatiile
logice pe care vrem să le facem pentru a colecta date dintr-o baza de date: conectarea la baza
de date, executarea de interogari ,si afisarea rezultatului .
Pentru a permite aceasta independenta de platforma, JDBC asigura un driver manager care
mentine în mod dinamic toate obiectele driver de care au nevoie interogarile bazei de date.
Daca avem trei tipuri diferite de baze de date la care vrem să ne conectam, vom avea nevoie
de trei obiecte driver diferite. Pentru a deschide o baza de date trebuie să cream un ”URL de
baza de date”, care specifica urmatoarele elemente :
1. faptul că folosim JDBC cu un “jdbc”
2. subprotocolul – numele driver-ului sau a mecanismului de conectare la baza de
date. Datorita faptului că design-ul lui JDBC a fost inspirat din ODBC , primul subprotocol
valabil este “jdbc-odbc bridge”, specificat prin “odbc’.
3. identificatorul bazei de date . Acesta variaza în funcţie de driver-ul bazei de date
utilizat, dar de obicei asigura un nume logic care e bazat de software-ul de administrare a
bazei de date într-un director unde tabelele bazei de date sunt localizate.

7
Pentru că identificatorul bazei de date să aiba inteles trebuie inregistrat numele care utilizeaza
software-ul de utilizare a bazei de date. Toate aceste informaţii sunt combinate într-un singur
string “URL-ul bazei de date”. De exemplu pentru conectare prin subprotocolul ODBC la o
baza de date indentificata sub forma “personal” baza de date URL poate fi :
String dbUrl = ”jdbc:odbc:personal”;

Daca ne conectam printr-o reţea, baza de date va conţine de asemenea informaţii de


identificare a calculatorului aflat la distanta. când dorim conectarea la baza de date facem apel
la metoda statica DriverManager.getConnection( ) şi că parametrii introducem url, nume de
user şi parola. Obţinem un obiect Connection pe care apoi il folosim pentru interogarea şi
manipularea bazei de date. Urmatorul exemplu deschide o baza de date ce conţine informaţii
de contactare şi cauta prenumele persoanei introdusa în linia de comanda.. Selecteaza numai
numele persoanelor care au adresa email, apoi afiseaza toate persoanele cu acest prenume
Exemplu:
//face cautare intr-o baza de date dupa email, folosind JDBC
import java.sql.*;
public class Lookup {
public static void main(String[] args)
throws SQLExcepţion, ClassNotFoundExcepţion {
String dbUrl = "jdbc:odbc:personal";
String user = "";
String password = "";
Try {
// incarca driverul
Class.forName(
"sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection(
dbUrl, user, password);
Statement s = c.createStatement();
// SQL code:
ResultSet r =
s.executeQuery(
"SELECT FIRST, LAST, EMAIL " +
"FROM personal.csv personal " +
"WHERE " +
"(LAST='" + args[0] + "') " +
" AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
while(r.next()) {
// Capitalization doesn't matter:
System.out.println(
r.getString("Last") + ", "
+ r.getString("fIRST")
+ ": " + r.getString("EMAIL") );
}
s.close(); // Also closes ResultSet
} catch (Excepţion e ) {
e.printStackTrace () ;
}
}}

8
Explicaţia codului:
In acest exemplu baza de date nu are protectie cu parola, deci numele de utilizator şi parola
sunt string-uri goale. Odata conectarea realizata cu DriverManager.getConnection() se
poate folosi obiectul rezultat Connection pentru crearea unui obiect Statement folosind
metoda createStatement(). Cu Statement-ul obţinut se poate apela executeQuerry() caruia i
se va da un string care conţine un statement SQL-92 standard. Metoda executeQuerry()
returneaza un obiect ResultSet care este asemanator unui iterator : metoda next() – muta
iteratorul la inregistrarea urmatoare din statement sau returneaza false daca s-a ajuns la sfarsit.
Intotdeauna se va obţine un obiect ResultSet de la executeQuerry() chiar daca aceasta
cerere resulta o inregistrare goala ( acesta este o excepţie care nu este prelucrata) . De
remarcat este faptul că trebuie apelat next() inca odata inainte de a incerca citirea oricarei
inregistrari. Daca rezultatul este gol, apelul lui next() va returna false. Pentru fiecare
inregistrare rezultata putem selecta campurile folosind numele campului sub forma de string.
De asemenea denumirile campurilor nu sunt CASE SENSITIVE. Determinam tipul returnat
prin apelul la getInt(), getString(), getFloat(). în aceasta faza avem informaţiile din baza de
date în format nativ JAVA şi putem utiliza folosind cod java normal. Cu JDBC intelegerea
codului este relativ simplu, problemă este legata de a face să funcţioneze pe sisteme
particulare.

Motivul ce creaza confuzie este faptul că trebuie să ne dam seama cum să facem că driver-ul
JDBC să faca incarcarea corect, şi cum să configuram o baza de date ce utilizeaza software de
administrare a bazei de date. Desigur, acest proces poate varia în mod radical de la un
calculator la altul.

P1. Gasirea driver-ului JDBC


Exemplul anterior conţine urmatoarea secventa :
Class.forName (“sun. jdbc.odbc.JdbcOdbcDriver”);
La instalarea JDK 1.1 nu exista fişierul JdbcOdbcDriver.class. Daca la incarcare se detecteaza
că declaratia este gresita, se va lansa excepţia.

P2. Configurarea bazei de date


Prin deschiderea control panel-ului observam doua icon-uri “ODBC”. Selectam cel de “32bit
ODBC”, celalalt fiind destinat compabilitatii inverse , cu 16 bit ODBC.
La deschiderea icon-ului apare un tabel ce conţine : “User DSN , System DSN, File DSN,
etc.. ”, DSN insemnand Data Source Name , adica denumirea sursei de date .
Astfel se poate observa că pentru bridge-ul JDBC- ODBC , singurul loc unde este importanta
setarea bazei de date este “System DSN” . De asemenea, vom dori testarea configuratiei şi să
cream interogari . Pentru aceasta, avem nevoie de configurarea bazei de date în “File DSN”.
Astfel Microsoft Query Tool va gasi baza de date. Importanta mai mare o are baza de date
care este folosita. Standardul ODBC suporta un număr de formate diferite pentru fişiere ,
incluzand chiar şi Dbase.De asemenea, include şi formatul ASCII separat prin virgula.

Am considerat baza de date “personal”pe care l-am exportat în format ASCII separat de
virgula . în “File DSN” se alege driver-ul de text să gestioneze acest fişier , dupa care se
deselectează “use current directory”, pentru a putea specifica driver-ului locul unde s-a
exportat fişierul de date. Fiecare fişier conţine de obicei un singur tabel, iar declaratiile
SQL pot da rezultate care sunt culese din mai multe tabele , ale bazei de date, (numit
join).Baza de date ce conţine un singur tabel , este numita flat file database. Majoritaea

9
problemelor legate de depozitarea şi regasirea datelor , presupun folosirea de baze de date ce
au mai multe tabele care sunt legate prin join. , numite baze de date relationale.
P3. Testarea configuratiei
Pentru realizarea acestui lucru avem nevoie de o modalitate de descoperire daca baza de date
este vizibila într-un program ce face interogarea.
Connection c = DriverManager.getConnection( dbUrl, user, password) ;
Daca apare excepţia, inseamna că configurarea nu a fost buna.
P4. Generarea de interogare SQL
Interogarea creata cu ajutorul Microsoft Query ne-a aratat doar că baza de date este acolo,
dar a creat în mod automat un cod SQL ce este necesar de inserat în programul Java. S-a
dorit crearea unei interogari care să asigure cautarea inregistrarilor în funcţie de prenumele pe
introdus în linia de comanda ce apare la rularea programului. Se caută un prenume specific ,
Petre. De asemenea, s-a dorit gasirea prenumelui persoanelor ce aveau atasata şi adresa de e-
mail. Se parcurg etapele:
- Se foloseşte Query Wizard pentru a crea o noua interogare. Se selectează baza de
date “personal ”, ceea ce este echivalent cu deschiderea conectarii prin specificarea
Url-ului bazei de date.
- Se selectează tabelul “personal” din baza de date, iar din table se alege coloanele
First, Last, Email.
- In “Filter Data”, se alege Last, se selectează “equals”, cu argumentul Eckel. Dacă
se apasa butonul Add, apoi
- Se alege Email şi se selecteaza “is not null”
- In “sort by ” se alege First. Se apasa butonul SQL, care va genera codul SQL care
va fi copiat.

SELECT personal.First, personal.Last, personal.Email FROM personal .csv personal


WHERE (personal.Last = ‘Eckel’) AND
( personal.Email Is Not Null )
ORDER BY personal.First

La interogarile mai complexe, se poate gresi usor, dar cu ajutorul lui Query Tool, se pot testa
interogarile, şi genera automat codul corect.

P5. Modificarea şi copierea în interogare


Se poate observa codul ce difera de cel folosit în program, deoarace Query Tool foloseste
calificari complete pentru toate denumirile, chiar şi în situatia în care baza de date are un
singur tabel (ca şi în cazul prezentat). Daca avem mai multe tabele, calificarea previne
producerea de coliziuni intre coloanele diferitelor tabele ale aceleiasi baze de date care au
aceeasi denumire. Dar pentru că în aceasta interogare se include un singur tabel, putem
elimina calificarile unor denumiri.

SELECT Firs, Last, Email


FROM personal.csv personal
WHERE (Last = ‘Eckel’) AND
(Email Is Not Null)
ORDER BY First

De asemenea vrem să se faca o cautare dupa prenumele introdus în linia de comanda. Cu


aceste modificari, şi transformand declaratiile SQL într-un String creat în mod dinamic, se
obţine :

10
“SELECT First, Last , Email” +
“FROM personal.csv personal” +
“WHERE” +
“(Last = ‘ ” + args [0] + “ ‘ )” +
“AND (Email Is Not Null) “ +
“ORDER BY First “;

De asemenea, SQL-ul are o alta modalitate de a insera denumiri intr-o interogare , denumita
stored procedures, care are avantaje legate de viteza.

Introducere în accesul database Client/Server

Relaţional database systems utilizează Relational Data Model – SQL


Object-Oriented database systems – adaugă persistenţă obiectelor, se focalizează pe orice
integrare stare aparentă a facilităţilor database cu un limbaj de programare specific, acces
navigaţional al obiectelor persistente.
OQL (Object Query Language) are faţă de SQL extensii la expresii path pentru acces
navigaţional şi învocarea metodelor.
Object Relational Database Systems – extind caracteristici obiectuale
SQL3 – noul limbaj relaţional-obiect
XQL (XML Query Language) extinde XML ca şi OQL
Embedded SQL – conţine atât comenzi statice SQL cât şi comenzi dinamice. Cele statice
sunt procesate în timpul compilării, cele dinamice la momentul rulării.
Call-level interface ca ODBC dezvoltă limitările Emdedded SQL
In cazul ODBC sau SQLJ (Embleded SQL) atenţia este regăsirea şi manipularea datelor
focalizarea fiind data-centric.
Pentru Java binding focalizarea este objects-centric.
XML – “the Lingua Franco on the Web”

(Web basics) Java Primer

Tipurile de date pentru accesul la RDBS sunt :


Byte, short, int, long, floty double, java_math.BigDecimal, String, boolean, byte[ ],
java.sql.Date, java.sql.Time, java.Timestamp.
Java.sql.Date, Time şi Timestamp extind java.util.Date reprezentând valori de SQL DATE.
SQL TIMESTAMP nano value este Timestamp din Java.

Java Events

Este destinat utilizării în AWT şi Java Beans, furnizor a unui mecanism de propagare sau a
state change notification notificare între un obiect sursă şi unul sau mai multe obiecte
listeners.
Modelul event furnizează un mecanism extensibil :
- furnizează un set de event types şi propagation methods pentru definiţii şi
aplicaţii ;
- permite descoperirea evenimentelor pe care obiectele clasei le poate genera sau le
poate observa ;

11
- furnizează un mecanism de înregistrare a evenimentelor ce permite manipularea
dinamică a relaţiilor dintre sursele evenimentelor şi event listeners.
- înalţă performanţă de propagare a evenimentelor între sursă şi destinaţie.

Event Source Event Source


listeners listeners

fire fire
event event
Event Event
Object register Object register
listener listener

Event Listener Event Adapter


destination

forward
event Event
a) Model Java Event
Object

Object

b) Model Java Event Adapter


Figura 1.1.Modele Event

Componentele cheie includ (figura 1.1.) :


• Event notification – propagat de sursele de ascultare prin method
invocation ;
• Event listeners – interfaţă ce extinde java.util.EventListener. Ele se
autoidentifică fiind interesate în observarea unui set de evenimente în
corespondenţă cu un set de Event Listener interfaces.
• Event Objects – stare asociată unei notificări este încapsulată în obiecte ce
extind java.util.EventObject şi care este trimis ca unic argument către metoda de
notificare.
• Event Source se autoidentifică ca o sursă ce generează evenimente
particulare, definind registrations methods conform cu designer pattern
acceptând referinţe la obiecte prin interfeţe specifice Event Listener.
• Event Adapter – se implementează când listeners nu pot implementa direct
o interfaţă ci se interpun între sursă şi unul sau mai mulţi listeners.

Java Archive (JAR)


- format de fişier independent de platformă ce agreghează mai multe fişiere (applets
Beans, enterprise Beans, class, recusite de componente).
Formatul JAR suportă : compresie (ceea ce reduce dimensiunea) şi semnătură digitală
pentru intrări individuale, ceea ce autentifică originea.
JAR conţine : arhive, sygnature file, manifest.

12
- Archive poate fi oricare format ce suportă căi reactivate
- Manifest file au cale META-INF/MANIFEST.MF şi conţine lista de fişiere
prezente în arhivă.
- Sygnature au cale META-INF/<nume-fisier>.SF

Java Tasting API conţine clase + interfeţe din pachetele:


- java.lang(Object, Class, Class Loader)
- java.lang.reflect (Member, Field, Method, Constructes, Analog, Modifie)
- java.lang pentru fire (Runnable, Thead, ThreadGroup)
- java.util (Event Listeney, Event Object) pentru evenimente.

DBMS & SQL


a) – Model relaţional, concepte
b) – Comenzi de control a datelor asigură data security şi data consistency
Security se referă la privilegii – oferite de GRANT şi anulate de REVOKE
[GRANT; REVOKE] privilegii on Objects, FROM USERS.
Aceste privilegii includ: select, insert, update şi delete caz în care rândurile pot fi şterse,
inserate.
Consistancy se referă la ACID (Atomicity Consistency Isolationa Durability)
SQL defineşte 4 nivele de izolare:
- Read Uncomited – citirea greoaie (dirty), nonrepetabilă şi phantom are possible;
- Read Cominited – nonrepetabilă şi phantom
- Repetable Read – phantom is possible
- Serializable – nici un fenomen posibil.
dirty read – tranzacţia poate vedea modificările făcute de alte tranzacţii concurente, înainte de
a se fi produs.
nonrepetabile read – tranzacţia poate citi un rând odată, dacă încearcă să îl citească a doua
oară acesta poate fi şters sau modificat de o altă tranzacţie concurentă.
phantom phenomenon – este un set de râduri citite de tranzacţie pot fi diferite de setul ce
încearcă să îl citească din nou
COMMIT – după comandă toate actualizările devin permanente
ROLLBACK – toate actualizările tranzacţiei sunt discharged
Conectarea are loc cu CONNECT to database
Terminarea conexiunii DISCONNECT database

OOD şi ODMG 2.0.

Object Oriented Database Systems (Object Oriented database management systems) s-a
dezvoltat adăugând persistenţă obiectelor utilizate în (OOPL) ca Small/talk sau C++ şi se
focalizează pe integrarea transparentă a facilităţilor DB cu limbajele de programare prin faptul
că:
- extend limbajele prin transparenţa datelor persistente, query associative, controlul
concurenţei, tranzacţii etc.;
- fac ca obiectele database să apară ca obiecte ale limbajului

Diferenţe arhitecturale în sisteme OODBS:


- persistenţa claselor versus persistenţa instanţelor. Cu persistenţa clase toate instanţele
unei clase persistente sunt prin definiţii persistente şi toate instanţele claselor nou-
persistente sunt tranzitive (transient). Cu persistenţa instanţelor, orice instanţă a

13
oricărei clase poate fi declarată şi făcută persistentă. Deci persistenţa este ortogonală
pe sau independentă de clasă, ceea ce afectează modelul de programare.
- diferenţe între limbajele de programare Smalltalk diferit de C++ diferit de Java diferit
de Cobol ceea ce face dificilă printarea aplicaţiilor dintr-un limbaj în altul.
- Page Server vs. object server In abordarea page server, serverul c “dumb” şi clientul e
“fat” apt că inteligenţa rezidă la client. In abordare object server, serverul e “smart” şi
clientul poate fi “thin”.

Transparent
Data Transfer

Figura 1.3. Object Oriented Databas

ODMG 2.0 Object Database Management Group elaborează standud pentru a asigura:
- portabilitate pentru schemele de date, limbaj de interogare şi legăturile cu limbajul
de programare;
- interoperabilitate între produsele OODB.
Standardul ODMG 2.0. are componentele:
1. Object Model – defineşte modelul OMG ce include modelul meta-object;
2. Object Specification Languages – constă din ODC (Object Definition Language)
care este definiţia schemei BD şi se bazează pe OMG Interface Definition Language
(IDL) şi Object Interchange Format (OIF) utilizat pentru a schimba obiecte între BD.
3. Object Query Language (OQL) – limbaj declarativ pentru cereri şi actualizări de
obiecte BD prevăzut de SQL.
4. OOPL Language Binding include Java, C++, Smalltalk. Orice legătură limbaj constă
din ODL şi OML (Object manipulation Language şi OOL pentru legături. Spre
deosebire de SQL, ODMG nu defineşte OML comune ci limbajul de manipulare a
datelor este potrivit spre limbaj de programare specific.

Modelul obiect şi ODL (Fig. 5)


OM defineşte constructori suportaţi de oricare OODS:
- constructorii modelului de bază sunt obiecte şi literali. Orice obiect are identificator
unic.
- Obiectele şi literalii cunt caracterizate prin types.
Toate instanţele pentru un tip dat au un nivel comun de stare şi componente comune.
- starea este caracterizată de valori ale proprietăţilor. Acestea pot fi attribute ale unui
obiect sau relaţii între obiect sau alte obiecte. Starea unui literal este caracterizată prin
valoare.
- comportamentul unui obiect este definit printr-un set de operaţii ce pot fi executate
de obiect. Literalul nu are comportament.

14
- BD stochează şi manipulează obiecte, permiţând partajarea lor la multipli utilizatori şi
aplicaţie. Oricare BD este definită prin schemă specificată în ODC.

Sursa aplicaţiilor în
Declaraţii în ODL
OOPL
sau OOPL ODL

Compilator
Procesor OOPL
Declaraţii
OODBS Application
Metadata Runtime Binary

OOPL
Linker

Data access
Database Running
Application

Figura 1.5. Utilizarea OODatabase System

Types sunt specificaţii pentru una sau mai multe implementări.


Specificaţiile definesc caracteristici externe ale tipurilor şi includ: proprietăţi ce pot fi
accesate, operatori ce pot fi invocaţi pe aceste instanţe şi orice excepţii ce pot fi acoperite de
operaţii. Implementarea defineşte aspecte interne ale tipului: implementarea proprietăţilor,
operaţiilor şi alte detalii interne (crearea şi individualizarea instanţelor).
Sunt 3 tipuri de specificaţii:
1. definirea interfeţei – comportament abstract al tipului obiect;
2. definiţia clasei – comportament şi stare abstractă a tipului obiect;
3. definirea tipului literal – starea abstractă a tipului literal.
OM suportă: long, shorty unsigned long, unsigned short floty double, char, string, (cu lungime
fixă sau variabilă) bolean, octet, enum, sequence, struct, union.

Moştenirea
OM suportă moştenirea comportamentului (relaţia is-a) şi moştenirea comportamentului şi
stării (relaţiile EXTENDS).

Extents & Keys


extents pentru un tip obiect este setul tuturor instanţelor de acel tip într-o BD particulară;
class Building (extent buildirep) {…}
class Church (extent churches) {…}
Key – pentru un tip obiect este proprietatea sau setul de proprietăţi a căror valori unice
identifică instanţe individuale de acel tip.
Exemplu:
class Building (extent buildings key name)
{….. atribute string <32> name;
----

15
};

Proprietăţi
OM suportă attribute şi relaţii ca proprietăţi:
• Atributele specifică starea reflectată a tipului
Exemplu:
class Building (extent buildings key name)
{
atribute string <32> name;
atribute string <32> type;
atribute string <256> address;
atribute City <32> city;
atribute long <256> yearBuilt;
atribute Architect <256> architect;
atribute sequence <char> description;
atribute sequence <octec> picture;
};
• Relaţiile
OM suportă relaţiile binare între 2 tipuri de obiecte. Relaţiile sunt definite implicit prin
declaraţia de traversal path (cale transversală) ce dau conexiuni logice între obiecte
participante la relaţie. Traversal path se declară pereche câte una pentru fiecare
direcţie.
Exemplu:
interface Professor {
---
relation ship set <Course> teaches
inverse course:: is_taught_by;
---
}
interface Course {
---
relationship Professor is_taught_by
inverse: :Professor: : teaches;
}

OODB este responsabilă de menţinerea integrităţii referenţiale ceea ce înseamnă că dacă un


obiect participant la relaţie este şters, orice cale transversală către acel obiect este şters.
Obs: O instanţă de curs se şterge prin is_taught_by este legat de un Professor, care la rândul
lui trebuie şters.

Operaţia
Comportamentul în OM este specificat ca set de semnături de operaţie (operation
signature). Fiecare semnătură defineşte numele specificaţiei şi numele şi tipul fiecărui
argument (in, ont, inout) tipul valorii intrate şi numele oricărei excepţii ce poate fi proiectată.
Exemplu:
class person {
attribute Date birth_date;
--
short age();
--

16
}

Obiecte
Obiectele sunt instanţe de clase ce sunt create pentru învocarea operaţiilor pe factory objects
ce implementează factory interface ( )
Exemplu:
interface Object Factory {
Object new ( )
};

Toate obiectele implementează următoarea interfaţă ce este moştenită implicit de toate


clasele:
Exemplu:
interface Object {
enum Lock _Type (read, write, upgrade);
exception LockNotGranted ( );

boolean same_as(in Object obj);


Object copy ( );
void delete ( );

void lock (in Lock_Type mode) raises (LockNotGranded);


Boolean try_lock (in Code_Type mode);
};

Ciclul de viaţă al unui obiect este specificat la momentul la care este creat. OM suportă 2
tipuri: transient şi persistent. Un obiect transient are alocată memoria în timpul execuţiei.
Un obiect persitent are alocată memoria şi este înmagazinat de OODBMS şi sunt de fapt
obiecte DB. Persistenţa obiectelor este ortogonală sau independentă de tipul obiectului.

Identificatorii obiect şi numele


Toate BDO au identificatorii unici în BD şi rămân aceeaşi pe durata ciclului de viaţă. Aceştia
sunt generaţi de OODBMS şi nu sunt vizibili utilizatorilor. Literalii nu au identificatori. O
BDO poate avea unul sau mai multe nume semnificative şi vizibile utilizatorului. Aceste nu
sunt unice şi pot fi utilizate ca puncte de intrare în BD.
Localizarea unui obiect în BD poate fi realizată prin :
- nume, care este independent de stare;
- key, dependentă de clasa obiectului şi este parte a stării obiectului;
- prin navigarea cu un obiect ce are nume şi cheie şi referă respectivul obiectului căutat
în mod direct sau indirect.
Obiecte atomice – definite de utilizator, nu sunt predefinite de OM.

Collection Objects – formată din elemente ce pot fi obiecte atomice, alte colecţii sau literali.
OM include: Set, Bag, List, Array, Dictionary.Fiecare din acestea moşteneşte interfaţa
Collection:
Exemplu:
interface Collection {
exception Invalid Collection Type };
exception Element Not Found (any element);};

17
unsigned long cardinality ( );
boolean is_empty( );
boolean is_ordered ( );
boolean allows_duplicates();

boolean contains_element (in any element);


void insert_element (in any element);
void remove_element (in any element) raises (ElementNotFound);

Iterator-ul este creat pentru traversarea colecţiei şi poate fi forward-only sau


BidirectionalIterator ce suportă traversări bidirecţionale.
Exemplu:
interface Iteration {
exception NoMoreElements { };
exception InvalidCollectionType ();

boolean is_stable( );
boolean_at_end( );
void reset ( );

void next_posistion ( ) raises (NoMoreElements);


any get_element ( ) raises (NoMoreElements);
void replace_element (in any element) raises (NoMoreElements);
};

interface BidirectionalIteration: Iterator {


boolean at_beginning ( );
wid previsions_position ( ) raises (NoMoreElements);
};

Un iterator stabil nu este afectat de modificările din colecţie în timpul traversării. Un iterator
odată creat se poziţionează la început.

Obiecte structurate
OM suportă Date, Time, Timestamp şi Interval ca şi SQL literali în OM:
• atomici: long short,…., char şi enum;
• collections: set, log, list, any şi direction;
• structured: date, time, timestamp, interval şi struct;
• null: oricare tip ce suportă valoarea null.

Tranzacţiile: OM suportă tranzacţii Acid


Există 2 interfeţe: Transaction Factory şi Transaction.
Crearea unei tranzacţii:
Exemplu:
interface Transaction Factory {
Transaction new( );
Transaction current( );
};
Odată ce obiectul Transaction este creat, el poate fi manipulate prin interfaţă:
Exemplu:

18
interface Transaction;
exception Transaction InProgress {};
exception Transaction NotInProgress {};

void begin( ) raises (TransactionInProgress);


void commit( ) raises (TransactionNotInProgress);
void abort( ) raises (TransactionNotInProgress);
void chechpoint( ) raises (TransactionNotInProgress);

void join ( );
void leave ( );

boolean is_open ( );
};

Explicaţii:
begin( ) – solicită deschiderea tranzacţiei
commit( ) - determină ca obiectele create sau modificate în timpul tranzacţiei să fie
scrise în BD şi eliberate toate blocajele. In viitor tranzacţia poate fi închisă.
abort ( ) – tranzacţia se completează şi devine închisă.BD revine în starea de dinaintea
tranzacţiei.
chechpoint() este echivalent cu commit( )+begin( ) doar că blocajele nu sunt eliberate.
join() şi leave() – se folosesc la tranzacţii multiple şi sunt alternate pe firele de
execuţie.

Operaţia asupra BD
OODBMS suportă manipularea unei/mai multor BD, fiecare reprezentând instanţă de tip
database creată prin:
Exemplu:
interface Database Factory ( ) {
Database new ( );
};
Odată ce obiectul Database a fost creat, el poate fi manipulat prin interfaţa:
interface Database {
void open (in string database_name);
void close ( );

void bind (in any obj, in string name);


Object unbind (in string name);
Object lookup (in string name);
Module schema ( );
};
unde:
• open() se învocă la oricare acces al BD;
• close() se invocă după completarea tuturor accesului la BD ;
• bind(), unbind(), lookup () permite asocierea numelor cu obiecte din BD şi utilizarea
lor la căutarea obiectelor.

19
Module – Meta-Object model

OQL furnizează acces declarativ la obiectele înmagazinate şi manipulate prin OOBDBMS ;


se bazează pe SQL-92 şi adaugă extensii OO:
- identitatea obiectului;
- obiecte complexe;
- expresii Path;
- invocarea operaţiilor;
- polimorfism şi legare dinamică (late binding).
Diferenţa majoră este că OOQL nu furnizează explicit insert(), update() şi delete() însă
depinde de operaţiile definite pe obiecte în acest scop.

Query
OQL permite cererilor să utilizeze obiecte sau literali ca puncte de intrare.
Exemplu:
SELECT x.type
FROM buildings x
WHERE x.name = “Washinton Monument”
Query poate returna:
- colecţii de obiecte:
SELECT x FROM building x WHERE x.type= “Monumment” returnează colecţia
de obiecte Building cu tipul “Monument”
- un obiect:
ELEMENT (SELECT x FROM buildings x WHERE x.name = “The Capitol”);
- o colecţie de literali:
SELECT x address FROM buildings x WHERE x.type = “Monument”
- un literal:
ELEMENT (SELECT x address FROM buildings x WHERE x.name = “The
Capitol”)
întoarce un şir cu adresa la “The Capitol”

Path expressions
OQL permite navigare cu notaţia (.) (dot)
Exemplu:
class City
----
{attribute string C<32> name;
attribute Country country;
attribute Sequence<octet> arch-map;
};
Căutăm clădirea b în oraş prin:
b.city.name
sau în ţară prin b.city.coutry_name presupunând că în clasa Country am definit:
class Country
---
{attribute string<32> name;

20
attribute sequence<octet> city_map;
Calea poate fi oricât de lungă dacă nu crează ambiguităţi.

Invocarea operaţiilor
OQL permite invocarea cu/fără parametru
class Person (extent persons)
{attribute Date birth_date;
---
relationship set<Person> children
inverse Person::parents;
relation ship set<Person> parents
inverse Patron:: children;
---
short ages( );
bolean lives_in(in string city);
---
};
Putem afla vârsat celui mai mare copil ce trăieşte în Paris:
SELECT max(SELECT C.age FROM p.children)
FROM persons p
WHERE p.lives.in (“Paris”)

OOQL permite polimorfism şi legare dinamică:


class ProjectMember (extends projectMembers)
{
string activities();
};
class ProjectLeader extends ProjectMember}
---
string activities ( );
---
};
class TestLeader extends ProjectMember}
string activities ( );
};
Dacă utilizăm:
SELECT m.activities
FROM project Member m
în funcţie de m current este invocată activities din Project Leader sau Test Leader.

VI. ArchWorld Sample Database


Poet 5.0 este primul OODBMS care se configurează legării ODMG Java.
ArchWorld este BDR cu 5 tabele: Country, Architect, Building şi Clurch.
Comenzile SQL DDL:
CREATE TABLE Country (name char(32) NOT NULL PRIMARY KEY, cityMap
IMAGE)
CREATE TABLE City (name char(32) NOT NULL PRIMARY KEY, country
CHAR(32), archMap IMAGE, FOREIGN KEY (country) REFERENCES Country)
---
Caracteristici:

21
- cheia primară şi integritatea entităţii (not null);
- integritatea referenţială;
- integritatea domeniului (constrângeri verificate).
Incluzând tipuri avansate (IMAGE, TEXT) în DBL UDB folosim:
CREATE DISTINCT TYPE IMAGE AS BLOB (32K)
CREATE DISTINCT TYPE TEXT AS CLOB (32K)

OODB ArchWorld are 5 clase, create cu comenzi ODMG ODL:


class Country (extent countries key name)
{
attribute string <32> name;
attribute sequence <octet> city_map;
};
class City (extent cities key name)
{
attribute string <32> name;
attribute Country country;
attribute sequence <octet> arch_map;
}
---
Caracteristici:
- Extents;
- Cheile primare;
- Referinţe obiect (identificatori);
furnizează:
- integritatea entităţii (not null);
- integritate referenţială;
- integritatea domeniului.

VII. JDBC
Object data access (ODA) are de-a face cu 2 domenii diferite OOPL şi DBMS. De aceea
ODA API are 3 variante de proiectare:
- JDBC focalizat pe acces la BD;
- JDBC focalizat pe un singur limbaj: Java;
- JDBC focalizat pe un singur tip de BD:
SQL şi JDBC mapează drivere având grijă de schema de mapare pentru fiecare sistem
individual.
Tipuri de drivere JDBC:
1. JDBC –ODBC bridge driver – nu accesează BD direct ci este dependent de back-end
ODBC driver care face acces actual la BD.
2. Native API – partly Java driver – implementat cu metode Java native scrise în C, nu
sunt portabile pe alte platforme şi nu sunt calabile pe appleturi din cauza
constrângerilor browserelor Web.
3. Net-protocol – all Java driver – implementate cu metode pure Java , folosesc DBMS
independente şi protocol reţea pentru comunicaţia client-server.
4. Native-protocol - all Java driver – implementat cu metode pure Java, DBMS native şi
protocol reţea pentru comunicaţia client-server.
JDBC – API – în pachetul java.sql conţine: Driver Manager, Driver Interface, Conection
Interface.

22
Java Application
Applet

JDBC API
JDBC Driver
Manager
JDBC Driver
JDBC – API
ODBC JDBC JDBC-Net
Bridge Driver Driver
Driver

ODBC Proprietary JDBC


Driver Protocol Middleware
Protocol

Figura 1.7. Arhitectura JDBC

Tranzacţiile:
O nouă Connection este în auto-commit în mod implicit; rezultă faptul că toate comenzile
SQL vor fi executate şi comise ca tranzacţii individuale. Dacă autocommit este dezactivat,
tranzacţia nu se va termina decât la apelul Connection.commit() sau Connection.rollback() în
mod explicit. Când o tranzacţie este terminată toate Statement, Prepared Statement, Callable
Statement şi ResultSet associate cu Connection sunt inchise. Se poate seta nivelul de izolare a
tranzacţiei prin apel la Connection.setTransactionIsolation() care au 5 nivele:
- NONE
- READ_UNCOMITED
- READ_COMMITED
- REPETABLE_READ
- SERIALIZABLE
Constantele clasei:
• TRANSACTION_NONE(int) - tranzacţii nesuportate
• TRANSACTION_READ_UNCOMMITED(int) – pot apare dirty reads, nonrepetable
reads şi phantom reads
• TRANSACTION_READ_COMMITED(int) – sunt prevenite dirt reads, nonrepetable
reads şi phantom reads pot apare
• TRANSACTION_REPETABLE_READ (int) dirty şi non_repetable sunt provenite,
restul pot apare
• TRANSACTION _SERIALIZABLE(int) prevenite toate.

Driver Interface
Connection Interface
Statement Interface – nu au parametri:
- execute Query ( ) pentru comenzi SELECT ALL întoarce obiect result Set
- execute Update ( ) – pentru UNSERT, UPDATE, DELETE sau comenzi DDD –
întoarce numărul de rânduri actualizate
- execute( ) – întoarce getResultSet(), GetUpdateCount() şi getMoreResults()

23
Exemplu:
struct.execute (query String);
while (true){
int rowCount= struct.GetUpdateCount();
if (rowCount >0)} //Update
System.out println(“Rows changed =” +rowCount);
struct.get More Results ( );
continue;
}
if (rowCount =0){ //DDL sau o actualizare -update
system out.println (“No rows update or DDL”);
struct.get.MoreResults( );
continue;
}
ResultSet rs = struct.getResultSet();
If (rs!=null) {
while (rs.next)){
---
}
struct.get MoreResults ( );
continue;
}
break;
}

Prepared Statement se foloseşte la precompilare şi execuţii SQL cu parametrii IN Prepared


Statement.
pstmt=con. prepareStatement ( “UPDATE BUILDING SET type = ? where
rooms=?”);
Parametrii IN se setează înaintea execuţiei prin metodele :
- setxxx( ) pentru tipuri de date predefinite (se mapează de exemplu tipul Java pe
tipul SQL);
- setObject() pentru obiecte Java. Dacă ţinta datelor SQL este specificată se face
conversia. Dacă nu se utilizează standardul Java la SQL pentru a mapa obiecte
Java pe tip de dată SQL.
- setAsciiStream(), setBinaryStream(), setUnicodeStream(), setează o cantitate mai
mare de date incrementale
NULL VALUES se setează prin SetNull
Aceleaşi metode ca şi la Statement, parametrii IN se setează pe tipuri predefinite setByte( ),
setShort ( )…

Callable Statement Interface


Obiectul CallableStatement se foloseşte pentru a executa proceduri stocate SQL cu parametric
IN, OUT şi INOUT.
Procedurile stocate se apelează în mod standard sau cu sintaxă escape:
{ call procedure_name[(?,?,…)]}
sau
{?=call procedure_name[(?,?,…)}
Crearea:

24
CallableStatement cstart = con.prepareCall( “{call getTestDate (?,?)}”)
Parametri OUT sunt înregistraţi şi înaintea apelului prin registerOutParameter() – cu clasă de
dată specificată SQL după execuţie sunt regăsiţi prin:
getxxx( ) care întoarce tip de date predefinite
getObject ( ) care întoarce obiecte Java
Parametrii INOUT sunt înregistraţi şi setaţi înaintea execuţiei: registerOutParameter(),
setxxx( ), setObject() iar după execuţie se foloseşte getxxx(), getObject()
Valori null se setează cu getxxx() şi se teastează cu wasNull()
Parametrii OUT au metode predefinite getBytes(), getShort(),… şi alte metode: getObject(),
wasNull()

Interfaţa ResultSet constă din set sau mutiset de date intrate de Query SQL
Cursorul este poziţionat la început se deplasează prin next()
Valori întoarse – se regăsesc prin index sau nume folosind: getxxx(), getObject(),
getAsciiStream(), getPrimaryStream(), getUnicodeStream(); wasNull() pentru valori null
Metode: ca şi la CallableStatement
Metode adiţionale:
class()
wassNull()
findColumn(String ColumnName)
getCursorName()
getMetaData()
getWarnings()
clearWarnings()

Interfaţa Result Set MetaData


Constantele clasei: columnNoNulls(int), column Nullable(int), columnNullableUnknown()
Metode:
getColumnCount() întoarce numărul de coloane din resultSet
getColumnLabel(int column) întoarce numele coloanei (string)
getColumnName(int column)
getColumnType(int column)
getPrecision(int column)
getScale(int column)
getColumnDisplaySize ( )
Pentru informaţii de catalog:
getCatalogName (int column) nume de catalogul tabelului
getSchemaName (int column) – numele schemei
getTableName (int column) – numele tabelei
Pentru proprietăţile coloanelor metodele întorc valori booleene
isAutoIncrement(int column)
isCaseSensitive(int column)
isCurrency (int column)
isNullable (int column)
isReadOnly (int column)
isSearchable (int column) - poate fi utilizat cu WHERE
isSigned ( )
isWritable ( )
isDefinedWritable()

25
Interfaţa DataBaseMetaData are peste 40 constante de clasă şi peste 130 metode.
Metode:
getURL()
getUserName()
getDatabaseProductName()
getDatabaseProductVersion()
getDiverName()
getMaxConnection() – număr maxim de conexiuni.
Metode pentru tabele:
- getTable(String catalog, String SchemaPattern, String tableNamePatt, String column
NamePattern, String types) – intrare cu un ResultSet cu informaţii (table catalog, table
Schema, table name, table type, connections)
- getColumns(String catalog, String SchemaPattern, String tableNamePatt, String
columnNamePattern)
- getPrimaryKeys(String catalog, String schema, String table)
- getImportedKeys(String catalog, String schema, String table)
- getExportedKeep(String catalog, String schema, String table)

Clasa SQL Exception


Obiectul SQLException conţine informaţii despre erori de acces la BD:
- şir ce descrie eroarea;
- şir “SQLState” ce respectă x/Open sau SQLState convention;
- număr de cod intern
SQLException este interfaţa ce extinde Exception.
Constructori:
SQLException()
SQLException(String motiv)
SQLException(String motiv, String SQLState)
SQL Exception (String motiv, String SQLState, int VendorCode)
Metode
getSQLState ( ) întoarce String
getErrorCode ( ) întoarce int
getNextException() întoarce obiect SQLException
getNextException(SQLException ex) – setează următoarea eroare

VIII. SQLJ
Elementele Embeded SQL sunt clasificate în 4 grupuri:
1. Comenzi SQL executabile, care manipulează definiţii SQL(CREATE, ALTER şi DROP,
GRANT şi REVOKE), date (INSERT, SELECT, UPDATE şi DELETE, OPEN, FETCH şi
CLOSE) şi tranzacţii (COMMIT şi ROLLBLACK; SET TRANSACTION şi SET
CONSTRAINES)
2. SQL Dinamic – comenzi utilizate pentru a fi pregătite şi executate la momentul rulării
(PREPARE) DESCRIBE şi EXECUTE, DEALLOCATE, GET DESCRIPTOR, SET
DESCRIPTOR.
3. Declaraţii – comenzi utilizate la definirea variabilelor host şi cursorului (BEGIN /END
DECLARE SECTION şi CURSOR)
4. Controlul programului – comenzi de management al sesiunilor SQL (SET
AUTHORIZATION, SET CATALOG, SET NAMES, SET SCHEMA, SET SESSION şi SET
TIME ZONE)

26
- conexiuni BD (CONNECT, SET CONECTION şi DISCONECT
- excepţii (WHEN EVER) şi diagnostic (GET DIAGNOSTIC)
SQLJ permite translatorului analiza în timpul compilării, verficări sintactice a comenzilor
SQL, verificări de tip pentru schimbul de date intrare Java şi SQL (ceea ce asigură
compatibilitate), verificarea schemei BD.
Cod sursă Java
cu Embeded
SQL SQLJ Source
SQLJ
Cod sursă Java Translat
cu apeluri la Java Source
JDBC
Compilator
Java Byte Code Java
cu apeluri la Java
JDBC executable

Drive
r
JDBC

Baza de date

Concepte SQLJ
Programele SQLJ conţin următorii constructori SQL:
- DDL (Data Definition Language) ca şi CREATE, ALTER şi DROP
- Queries: Comanda SELECT şi expresii
- Comenzi de date: FETCH… INTO şi DELETE… INTO
- DML (Data Manipulation Language): INSERT, UPDATE, ELETE
- Apel de funcţii definite de utilizator
- Apel de proceduri stocate
- Managementul tranzacţiilor: COMMIT şi ROLLBACK
- Directive de sesiune
Variable host: se utilizează la transmiterea argumentelor de la Java la comenzi SQL. Un
identificator Java apare în comenzi SQL prefixat de :
Exemplu:
SELECT name, City FROM Building WHERE: YM Year Built
SELECT name, year Built INTO : n, :y FROM Building
WHERE name =”Lincon Memorial”
Clauzele SQL sunt formate din token # sql urmate de comenzi SQL incluse în {}.
Exemplu:
# SQL { DELETE FROM Building};
Contextul de conectare BD - obiectul connection-context reprezintă BD conectată şi apare
ca paranteză :
# sql (con) {DELETE FROM Building};
El este o instanţă a clasei connection-context:
# sql context AWConnect
Această clasă are metode de deschidere a conexiunii pentru o schemă BD, un URL dat,
utilizând şi parolă, ce ar trebui precizate înaintea execuţiei comenzilor SQL.

27
Exemplar Schemas
Este posibilă utilizarea schemei model (exemplar schema) ce conţine tabele, views, program
şi privilegii solicitate pentru operaţii SQL. Aceasta devine actual runtime schema.

Iteratori ResultSet
Obiectul iterator resultSet conţine set de rezultate selectate printr-un query. Iteratorii pot fi
lined_by_position sau bind_by_name, nu ambele variante.
Exemplu:
# sql public iterator ByPosition (string, int);
//folosit la query pentru nume şi anul construcţiei
{
By Position posIter;
String name;
int year;
# sql posIter = { SELECT name, yearBuilt FROM Building};
while true {
# sql {FETCH : posIter INTO :name, :year};
if (poster.end Fetch( )) break;
System.out println (name +”was built in” + year);
}
}
Exemplu:pentru bind_by_name
# sql public iterator ByName(String name, int year);
{
ByName nameIter;
# sql nameIter={SELECT name, yearBult FROM Building};
while (nameIter.next( )){
System.out println (nameIter.name( ) + “was built in” +
nameIter.year( ));
}
}

Funcţia de utilizator înseamnă construcţii SQL VALUES de tipul:


{
int x;
# Sql x = { VALUES (F1(35))};
}
unde F1 – funcţie definită de utilizator.

Procedurile stocate sunt definite cu CALL


# sql {CAU Proc1(: arg)};
şi pot avea IN, OUT, INOUT ca parametri
Specificaţiile SQL – nu afectează firele de execuţie şi sincronizare a acestora. Sunt 3 tipuri de
clauze:
- declaraţie de conexiune;
- declaraţie iterator;
- clauze executabile;
host_variabile = = : java_id
# sql [connection] [glue] [sql]

28
↓ ↓
context conexiune Java token şi variabile
comenzi SQL, expresii

Conexiunea BD
# sql [modifies] context java_id;
ca şi la clase Java (public,protected, etc…)
Exemplu:
# sql context AWConect;

Interfeţe ConnectionContext – este conţinută în pachetul sqlj.runtime


Constantele de clasă: CLOSE_CONNECTION (boolean)
KEEP _CONNECTION (boolean)
Metode:
getConnectedProfile(Object profileKey)
getConnection()
getExecutionContext ()
close()
isClosed()

Interfaţa ExecutionContext – asigură controlul execuţiei rapoarte de stare şi termină


execuţia.
Constante: QUERY_COUNT(boolean)
EXCEPTION_COUNT(boolean)
Constructor: Execution Context( )
Metode de accesare:
get MaxFieldSize()
getMaxFieldSize() Metode adiţionale
getMaxRows() executeQuery()
getMax Rows() executeUpdate()
getQueryTimeout() cancel()
getQueryTimeout() registerStatement()
getWarnings() releaseStatement()
getUpdateCount()
AWConnectClass implementează interfaţa ConnectionContext şi are
constructori:
AWConnect (String url) interfaţă conexiune între BD reprezentate de url;
AWConnect (String url, String user, String password) –solicită în plus utilizator şi
parolă;
AWConnect(String url, java.util.Proprieties.info) – utilizează info date;
AWConnect(ConnectionContext other) - împarte aceeaşi conexiune BD cu alt obiect
ConnectionContext;
AWConnect (java.sql.Connection conn) - împarte aceeaşi conexiune BD cu o
conexiune JDBC conn
Metode
getDefaultContext() întoarce obiectul AWConnect în context conexiune;
getDefault; Context(AWConnect ctx) - setează obiectul context conexiune pe un
obiect ctx dat;
getProfileKey(sqlj.runtime.profile.Loader, String profileName) întoarce o cheie de
profil de tip Object pentru loader şi nume specificat.

29
Conexiune implicită
Dacă invocarea translatorului SQLJ ridică clasă AWConnect clauzele ce utilizează
conexiunea implicită vor fi translatate astfel:
# sql (AWConnect, getDefaultContext( ) {UPDATE Building
SET year Built = :y WHERE name = :n);
sau
# sql (AWConnect.setDefaultContext (new AWConnect(argv[0]
unde argv[0] sunt furnizate prin linia de comandă.

Construcţii SQL
Fiecare construcţie SQL poate apare în clauze de atribuire care evaluează construcţia SQL şi
atribuie valorile unui parametru Java, variabile sau câmp.
# sql posIter = {SELECT name, yearBuilt FROM Building};
Mai pot apare clauze de comandă ce se execută în construcţia SQL.
# sql {DELETE FROM Building} ;
DDL (CREATE, ALTER, DROP) pot apare în clauze de comenzi.
Query – comenzile SELECT pot apare în clauze de atribuire dacă nu conţin INTO.
# sql {SELECT name, city FROM Building WHERE :y> yearBuild;
Select … INTO şi FETCH … INTO pot apare în clauze de comandă.
# sql {SELECT name, year Built INTO :n, :y FROM
Building WHERE name = “Lincron Memorial”}
DML (INSERT, UPDATE şi DELETE) apare în clauze comandă
Apelul funcţiilor definite de utilizator:
VALUES (sql_name (arguments))
unde:
sql.name = = [[catalog_id.]schema_id.]sql_id
catalog_id = = sql_id
schema_id= = sql_id
Apelul de proceduri stocate pot avea parametri IN, OUT, INOUT
CALL sql_name(arguments)
Blocuri SQL apar în clauze de comandă :
# sql {BEGIN
DELETE FROM Building;
INSERT INTO Building (name, yearBuilt) VALUES
(: n, :y);
END};
Interfaţa ResultSet Iterator împarte funcţionalitatea iteratoarelor şi are metodele:
- next() avansează iteratorul la rând nou
- getResultSet() întoarce java.Sql.ResultSet asociat iteratorul
- rowCount()
- close( )
- isClosed( )

Interfaţa ForUpDate trebuie să implementeze iteratori de poziţionare utilizaţi în actualizare


sau ştergere.
getCursorName( ) întoarce (String) la cursor SQL
Interfaţa PositionalIterator extinde ResultSetIterator şi are metoda:
endFetch( ) dacă FETCH se poziţionează după ultimul rând, în plus poate oferi şi
constructor public ce ia JDBC result Set ca parametru.

30
Prin getColN oferă o metodă de accesare la fiecare coloană, unde N este a N-a coloană.
Interfaţa NamedIterator extinde ResultSetIterator.

Clauze executabile
Clauze de atribuire
# sql [connection] java_lhs={expr.};

left hand side
Clauze de comandă
# sql (connection){strut};
Poziţionarea la ştergere şi actualizare:
WHERE CURRENT OF host_variabila
Exemplu:
# sql {UPDATE Building SET yearBuilt = :y WHERE
CURRENT OF posIter};
Valori null sunt manipulate prin:
Integer y = null;
# sql {UPDATE Building SET yearBuilt = :y WHERE
name = :n};

Pachetele Runtime
 sqlj.runtime include clase şi interfeţe ca şi ConnectionContext, ExecutionContext,
ResultSet Iterator, NamedIterator, PositionedIterator şi ForUpdate
 Sqlj.runtime.ref include clase RTPrepared Stratement, RTCallableStatement,
RTResultSet
 Sqlj.runtime.error manipulează erorile
 Sqlj.runtime.profile include clase şi interfeţe ca Profile, ProfileData, EntryInfo,
TypeInfo, PositionedDescripor ConnectedProfile şi Customisation
 Sqlj.runtime.profile.ref include clase ca şi JDBCProfile, PositionedProfile,
TransactionControlProfile şi TypeRegisterProfile. In plus au clase ProfileWrapper,
PreparedStatementWrapper, CallStratementWrapper şi ResultSetWrapper.
 Sqlj.runtime.profile.util include clase ca DataCustomizer şi ProfilePrinter.

Schema cadru de SQL executabil


Procesarea SQLJ implică 3 faze: translaţia, instalarea şi execuţia.
Generarea codului utilizează schema:
- ia ConnectedProfile din context conexiune;
- ia JDBCPreparedStatement sau CallableStatement din profilul conectat;
- acoperă comenzile cu RTPreparedStatement sau RTCallableStatement
- leagă intrările folosind metode setxxx()
- execută comenzile folosind executeQuery() sau ExecuteUpdate()
- ia ieşirile cu metode getxxx()
- închide comenzile prin close()
Restricţii:
- contextul conexiunii trebuie să implementeze getConnectedProfile metodă ce ia
profile key ca parametru;
- iteratorii sunt constructorii publici ce iau JDBC resultSet ca parametru

Profilul

31
Connection Connection
Context Class Context Instance

Connection

Connected
Profile Connected
Profile Profile
Profile

Translation Time RunTime


Figura 5. Relaţiile Context Conexiune Profil

Profilul conţine date de profil ce constau din una sau mai multe entry info (informaţii de
intrare). Un profil descrie complet asocierile aplicaţiei SQLJ.
Profilul de conexiune asigură posibilitatea aplicaţiei şi urmează regulile:
 textul SQL este interpretat şi gata de execuţie;
 are aceeaşi execuţie ca şi cum JDBC ar fi utilizat în execuţie dinamică;
 toţi parametrii OUT au fost înregistraţi.
Optimizare tipică include:
- transformarea textului SQL într-o formă ce permite execuţie eficientă;
- verificarea batch( ) şi/sau pregătirea profilului intrări;
- distribuirea şi/sau încărcarea la distanţă a intrărilor custom ;
- înregistrarea tipurilor custom pentru surse de date specifice ale parametrilor de
intrare;
- unificarea comportamentală a drivelor JDBC multiple.
Managementul profilului (figura 5) impune ca:
- la translaţie profilul trebuie generat şi împachetat;
- la instalare profilul poate fi optimizat;
- la rulare profilul trebuie instanţiat şi resolved (resoluţionat).
La translatare, oricare clasă connection context manipulează colecţia de instante de profil. La
rulare, oricare clasă connection context manipulează instanţe de profil de conexiune prin chei
de profil.
Profilul poate fi împachetat în fişiere JAR ce conţin:
- clasele scrise de client ;
- clasele generate SQLJ
- profilele de serializare generate de SQLJ
Customization presupune serializarea obiectelor prin metodele :
- registerCustomization()
- replaceCustomization()
- deregisterCustomization()
Instanţierea este realizată cu metoda Profile.instantiate().
Rezoluţiile de profil de conexiune sunt posibile prin obiectul Customization are metode ce
acceptConnection() şi getProfile()

Profile
Profile

Connection
32
Customization Connected
Customization Connected
Profile
Profile
Figura 6. Rezoluţiile de profil de conexiune

IX. Java Binding for OODB

Ciclul de viaţă obiect


O aplicaţie BD începe procesarea accesând unul sau mai multe obiecte (root objects). Aceste
obiecte sunt persistente şi furnizează poarta de intrare la BD; există un singur nivel de
nume/BD şi toate numele în BD particulară sunt unice. Metodele de manipulare a numelui
sunt definite în clasa Database. In legarea Java persistenţa nu este legată de nici o parte din
ierarhia de clasă sau specificaţia la momentul creării obiectului. Un obiect transient poate
deveni persistent automat dacă este referit de un obiect persistent în timpul unei tranzacţii.
Comportamentul se numeşte persistence by reachability. Instanţele claselor ce nu sunt
persistence-capable class nu sunt persistente, chiar dacă sunt referite de un obiect persistent.
Este posibil de declarat un câmp transient dacă valorile lui nu sunt înmagazinate în BD.
Static fields sunt tratate ca transient fields. Modificările obiectelor persistente sunt automat
reflectate în BD când tranzacţia în care au avut loc este commited. Un obiect este automat
şters din BD dacă nu este numit sau referit de alt obiect persistent.

Interfeţele Collection (Set, Bag, List extend Collection)


Interfaţa Collection are:
public interface Collection {
public int Size();
public boolean isEmpty( );

public boolean contains (Object obj);


public void add(Object obj);
public Object remove (Object obj);

public Ennumeration elements();

public Object selectedElement (String predicate);


public boolean existsElement(String predicate);

public Ennumeration Select (String predicate);


public Collection query (String predicate);
}
Interfaţa OMG Iterator este mapată pe interfaţa Enumeration.

Tranzacţiile
Crearea, accesul şi modificarea obiectelor persistente trebuie făcută într-o tranzacţie.
Obiectele transient nu fac parte din semantica tranzacţională. Clasa Transaction este definită
prin:
public class Transaction {

33
public static final int READ, UPDATE, WRITE;
public static Transaction current();

Transaction() ;

public boolean is_open();


public void begin();
public void comunit();
public void checkpoint();
public void abort();
public void join();
public void leave();
public void lock(Object obj, int mode);
}

Inaintea execuţiei oricărei operaţii trebuie creat un fişier, ce crează obiectul tranzacţiei sau se
asociază cu un obiect tranzacţie existent ce trebuie deschis. Sunt 3 moduri în care se folosesc
firele la tranzacţie :
1. Exact 1 fir face operaţia pe BD, pe o singură tranzacţie
2. Pot fi mai multe fişiere, fiecare având o singură tranzacţie. Programatorii NU
trebuie să paseze obiectele de la un fir la altul ce rulează pe tranzacţii diferite,
deoarece ODMG 2.0 nu defineşte rezultatul unui asemenea comportament.
3. Mai multe fire împart una sau mai multe tranzacţii. Programatorii trebuie să aibă
grijă de controlul concurenţei prin sincronizări Java.

Operaţii BD

BD sunt reprezentate de Java OML ca şi clase Database


public class Database {
public static final int notOpen = 0;
public static final int openReadOnly = 1;
public static final int openReadWrite = 2;
public static final int openExclusive = 3;
public static final int Database open (String database_name int access_Mode);
public void clase ;
public void bind ( Object obj, String name) ;
public Object unbind ( String name ) …;
public Object lookup ( String name ) ….;
};

Clasa nu are construtori, doar metode, open() şi permite crearea şi deschiderea unei BD. Orice
BD trebuie deschisă înaintea oricărei tranzacţii şi închisă după aceea; bind() şi unbind()
permite manipularea numelor de obiecte iar lookup() permite acces la obiect prin nume.

Java OQL
Interfaţa Collection furnizează metode de interogare; semnătura,etc.
public Object selectElement (String predicate) ;
public boolean existsElement (String predicate) ;
public Enumeration select (String predicate) ;
public Collection query (String predicate) ;

34
unde - predicate – şir cu sintaxă WHERE din clause SQL
OQLQuery – clasă ce permite crearea interogării, transfer de parametri, execuţia interogării şi
obţinerea rezultatelor
class OQL Query {
public OQLQuery ( ) { }
public OQL (Query (String query) {…}

public create (String query) {…}


public bind (Object parameter) {…}

public Object execute( ) … {…}


}
unde query – şir cu sintaxă OQL ce conţine parametric notaţi $I, unde I este rangul. Parametri
sunt setaţi cu metode bind( ).

Poet 5.0
Poet Java SDK complies ( ) ODMG Java binding. Utilizează concept de preprocess ce
modifică surse Java, adaugă suportul persistenţei şi crează schema BD pentru obiectele
persistente. OBD Poet are: dicţionar (sau schema BD) şi BD. Dicţionarul conţine informaţii
despre structura claselor persistence-capable. Un dicţionar poate fi împărţit de orice număr de
BD. La deschiderea BD Poet deschide dicţionarul şi îl asociază cu BD.

Clasele persistente sunt declarate în fişierul de configurare. Se poate crea un obiect Extent
pentru o clasă persistentă ce suportă clase extinse declarate în fişierul de configurare. Indecşii
se declară în fişierul de configurare. Se poate folosi un index în corespondenţă cu obiectul
Extent pentru a facilita navigarea şi regăsirea obiectului. Poet poate lega diferite obiecte cu
nume “null” care pot fi făcute persistente dar nu pot fi accesate prin nume.

Exemplu:Class Country
import COM.POET.odmg.*;
import COM.POET. odmg.collection.*;
import java.util.Date;

class Country
{
String name
byte [ ] city Map;
public Country (String n) {
name = n;
}
public String toString( ) {
return name;
}
}
Fişierul de configurare POET
[schemadata\ Country_dict]
oneFile = true
[databases\ Country_base]
oneFile= true

35
[classes\Country]
persistent = true
hasExtent = true
[Indexes \Country Name]
class = Country
members = name

Clasa principală este:


import COM.POET.odmg;
public class Main {
public static void main(String(J args) throws ODMG Exception{
if (args.lenght <1){
System.out.println(“Numele BD este “+” command line option”);
System.exit(1);
}
Database dcb=Database.open(args[0], Database.openReadWrite);
try {
doit (db);
} finally {
db.close ( );
}
}
static void doit(Database db) throws ODMGException {
transaction tnx = new Transaction(db);
tnx.begin ( );
try {
Country obj;
obj = new Country “USA”);
db.bind(obj, null);
obj = new Country(“France”);
db.bind (obj, null);
obj = new Country(“China”);
db.bind(obj, null);
txn.checkpoint( );
//regăsim toate instanţele Country cu clasa Exent
Extent countries = new Extent (db.”Country”);
while (countries.hasMore.Elements( )){
System.out.println(countries.nextElement( ));
}
}
catch(ObjectNameNotUniqueException exc){
txn.abort( );
trow exc;
}
catch (ODMGRoutine Exception exc){
txn.about( );
trow exc;
}
txn.commit( );
}

36
}

Problema majoră pentru OODB este dificultatea de a scrie aplicaţii prezente pe una sau mai
multe OODB. Din păcate caracteristici majore Java au rămas nedefinite în ODMG 2.0:
- clase persistence – capable;
- extends;
- keys;
- relaţia;
- acces la metadate.

X. Sample Data Access Application

Un sistem BD constă dintr-o parte BD client şi una BD server caz în care BD server poate
rula pe host. (figura 7.)

Java Application

Client
Database
Client
Intranet
Serv
er Database
Server

Baza de date

Figura 7. Data Access Application

Nu toate SGBD permit crearea BD cu JDBC; altele folosesc unelte GUI ce permit atribuirea
utilizatorilor şi parolelor. Dacă folosim JDBC-ODBC bridge, driverul va accesa orice BD care
are un driver ODBC (figura 8).

Java Application

Client
JDBC Driver
Manager
JDBC
Application
Driver
Intranet

Server Database Server


37

Baza de date
Figura 8. Acces cu JDBC-ODBC bridge

Exemplu: Clasa Init ArcWorld


public class InitArcWorld{
public static void main (String []args){
if(args.length ! =3){
System.out.println(“Usage:java InitArcWorld”+
“<dataSourceName><uid><pw>”);
System.exit(0);
}
try {
ArcWorld aw = new ArcWorld( );
aw.init(args[0], args[1], args[2]);
System.out.println(“ArcWorld iniţializată”);
} catch (Exception e) {
System_err.println (“eroare de iniţializare”);
e.printStackTrace( );
System.exit(1);
}
System.exit(0);
}
}

Clasa InitArcWorldData
public class InitArcWorldData {
public static void main (String []args){
if(args.lenght ! =3){
System.out.println(“Usage:java InitArcWorld”+
“<dataSourceName><uid><pw>”);
System.exit(0);
}
try {
ArcWorld aw =new ArcWorld ( );
Aw.initData(args[0], args[1], args[2]);
System.out.printler(“Date ArcWorld iniţializate”);
} catch(Exception e) {
System_err.printler(“Eroare date”);
e.print Stach Trace( );
System.exit(1);
}
System.exit(0);
}
}

38
Clasa ArcWorld
import java.sql.x;
public class ArcWorld {
public wid init (String ds, String uid, String pw) throws Exception {
Connection con = connect (ds, wid,pw);
dropTables(con);
createTable(con);
disconnect(con);
}
public wid initDate(String ds, String wid, String pw) throws Exception {
Connection con = Connect(ds, wid, pw)}
deleteData(con);
disconnect(con);
}

SQLJ
Accesul la date poate fi realizat prin SQLJ Reference Implementation dezvoltată de Oracle.
• Insert – inserează date în table, respectând ordinea impusă de constrângerile
referenţiale; se inserează o singură tranzacţie;
• Select – query în BD;
• Update – actualizează BD într-o singură tranzacţie;
• Delete – şterge datele respectând constrângeri referenţiale, într-o singură tranzacţie.
Toate aceste clase folosesc numele sursei de date, id, password.
Observaţii:
1. Toate fişierele sursă au extensie .sqlj;
2. Se rulează sursa folosind translator (sglj);
3. Translatorul generează surse Java standard cu acelaşi nume şi extensie *.java;
4. Se apelează java.c rezultă *.class.
5. Se utilizează iterators_by_name în aplicaţii simple.
6. SQLJ este propunere de standardizare ANSI/ISO.
Varianta 3 POET

XI. Dynamic Web Pages

SQL
HTML HTML Query BD
Form Form
R

CGI SQL Query Results


Web HTML Web HTML
Programs
Browser Report Server Report
Request Other
Back-
Respons ends
e
Figura Fluxul de procesare http pentru appel CGI

39
Net Data este un Web Gateway Tool ce furnizează un cadru robust şi scalabil pentru crearea
paginilor dinamice Web dintr-o varietate de surse. A apărut în 1995 când suporta DB2 şi se
numea DB2WWW Connection. In 1996 şi-a adăugat suport de acces multiplu.
Evoluţia Web Data Access:
1994 – documente statice HTML
1995 – aplicaţia server-side cu unelte Web middleware
- limitarea surselor de date
- procese statice CGI
1996 – procese client-side cu applet Java
- procesare server-side cu JDBC
- surse de date multiple
- Web Server API
1997 – programare vizuală
- Java servlets (server_side includes)
- mare varietate de surse şi platforme
2000 şi perspective – SQLJ
- XML

Arhitectura NET DATA

Formulare FormeHTML
Formulare HTML Query SQL
WW Apeluri de
HTML W funcţii
Applet
Java System
Web Perl, ASP,
Server PHP
Web RexApplet
X
NET.Data Java Database
Client
Appletcation server
server Web
Server
Acces la Baza de
Date

40
Figura Arhitectura Net.DATA

Net.Data constă din:


- macro processor – core of Net.Data, ce invocă apel de funcţie, leagă media de
programare şi generează pagini HTML;
- macro fişiere – aplicaţii scrise de utilizator;
- biblioteca de funcţie
- mediile de programare – external backend sau BD
- live connection – executabil, distinct ce menţine conexiunea între BD şi JVM
Macroprocesarea
Macro Net.Data procesează fişierul de 2 ori:
1. De pe browser Web utilizatorul invocă macroprocesorul cu un URL ce specifică
macroprocesorului, numele macro fişierului şi secţiunea HTML ce defineşte intrările
formei obiectului generează apoi o formă ce o întoarce Web serverului spre afişare.
2. Utilizatorul submit HTML a cărui attribute conţin URL ce specifică macro
procesorului numele macro fişierului şi numele secţiunii HTML ce defineşte ieşirile
(output) în HTML …. Din nou se procesează fişierul ce conţine funcţia SQL sau BD
invocată de alţi utilizatori tradient.

Apelul macroprocesorului:
attp://server_name/cgi_dir_name/db2.www.exc/macro_filename/macro_balde_name
Pt. cgi sau ICAPI
Bttp://server_name/macro_filename/macro_blade_name
Pentru NSAP, (Netscope Server API) sau ISAPI(Microsoft’s Internet_Server API)
Macroprocesorul execută task-urile:
- include fişiere, defineşte variabile şi funcţie;
- rezolvă referinţele de variabile şi invocă apel de funcţie
- încarcă bibliotecile specifice limbajului
- generează pagini standard ATML

WebServer http
WW IBM ICS
Formulare W Process
Server CGI Netscape
HTML Microsoft
API
Net.Data Net.Data
Applet Macro Macro
DLL
Java Function
Web
Client Processor Library

NET.DataLanguage
JavaEnvironment
Java Perl, System User
Rex
Applet Applicatio ASP, Writte
X
n PHP n

Native
RDB ODBC JDBC
File
Support Support Support
Live
Connectio
n

DB ODBC File
41
Oracle Source
2
s
Stored Procedures
Extenders
Figura Arhitectura componentelor Net.Data

42

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