Professional Documents
Culture Documents
CUPRINS
Introducere ................................................................................................................... 3
Principalii indicatori de fiabilitate a sistemelor ........................................................ 3
Caracteristici generale ale object relational mapping ................................................... 6
Contextul .................................................................................................................. 6
ORM (Object Relational Mapping) .......................................................................... 7
Motivaia dezvoltrii unui sistem de ORM .............................................................. 8
Descrierea proiectului ............................................................................................... 9
Alegerea Platformei .................................................................................................... 10
Tehnologii folosite...................................................................................................... 11
IDE (Mediu integrat de dezvoltare) ........................................................................ 11
Sisteme de management ale bazelor de date relaionale ........................................ 14
PostgreSQL......................................................................................................... 14
Microsoft SQL Server ........................................................................................ 15
API-uri folosite ....................................................................................................... 15
API-ul de JDBC(Java Database Connectivity)................................................... 16
API-ul de Reflection ........................................................................................... 17
API-ul de SWT(Standard Widget Toolkit)......................................................... 18
API-ul pentru crearea de fiiere PDF ................................................................. 20
Dezvoltarea aplicaiei ................................................................................................. 21
Cerinele aplicaiei .................................................................................................. 21
Arhitectura .............................................................................................................. 22
Strucura proiectului ................................................................................................ 23
Funcionalitile sistemului i tratarea problemelor ............................................... 26
Concluzii................................................................................................................. 38
Bibliografie ................................................................................................................. 38
Introducere
Fiabilitatea este un domeniu interdisciplinar care studiaza legile degradarii in timp a elementelor si
sistemelor. Este necesar sa se cunoasca cat mai exact care este nivelul real al fiabilitatii, astfel incat, in functie
de acesta, sa se stabileasca durata misiunii, perioadele de revizie si elementele de siguranta.
Descrierea matematica a fiabilitatii unui sistem poate fi facuta la nivel global, ignorand structura
sistemului, sau la nivel structural, luand in consideratie elementele sistemului si relatiile dintre ele. In ambele
cazuri caracterizarea fiabilitatii sistemului va folosi teoria probabilitatilor.
Notaii i Abrevieri
TABEL A
Obiect A
SGBD
ORM
TABEL B
Obiect B
Din figura de mai sus se observ corespondena Obiect A Tabel A , respectiv Obiect B Tabel
B.
Dei faptul c asigur comunicarea cu baza de date este un aspect foarte important,
ORM-ul mai are o serie de avantaje precum :
a)
Independena fa de baza de date acest fapt reprezint un avantaj major al
sistemului ORM deoarece nu conteaz sistemul de management al unei baze de date relaionale
folosit, n Java codul folosit va fi acelai, metodele nu vor avea ali parametri sau nu vor avea
alte rezultate. Schimbarea sistemului de management al bazei de date nu va determina
schimbarea vreunei linii de cod n Java.
b)
Simplitatea Este mult mai uor de lucrat cu obiecte n Java i de folosit
principiile POO dect lucrul cu cod SQL. n SQL, atunci cnd se depete un anumit grad de
dificultate lucrurile pot deveni foarte ncurcate, pe cnd n Java tot timpul vor fi mai uor de
prelucrat datele i de folosit aa cum ne dorim.
c)
Scalabilitate Sistemul va funciona la fel indiferent de dimensiunea bazei de
date, a tabelelor sau a tipurilor de date folosite
d)
Rapiditate Operaiile dorite se vor executa ntr-un timp foarte scurt, rezultatele
vazndu-se imediat
e)
Un mare avantaj pentru programator este reprezentat i de faptul c nu va mai fi
nevoit s realizeze o conexiune de fiecare dat i s apeleze la concepte de JDBC, conexiunea
se va face automat cnd va fi nevoie iar datele vor fi salvate n obiecte.
f)
ntreinerea codului i depanarea lui va fi foarte uoar avnd n vedere cantitatea
de cod mult redus i uurina cu care acesta poate fi neles.
Prima din ele este necesitatea specificrii printr-un parametru a numelui coloanei din
baz sau numele cmpului trebuie s se potriveasc cu numele coloanei din tabel. Prin
soluia propus am fcut s nu mai fie necesar potrivirea de nume, am considerat c
tratarea cheii primare ar trebui s fie una special, n sensul c ar trebui sa fie mai uor
de mapat, nu mai greu dup prerea mea, ca n Hibernate.
A doua problem la maparea cheii primare este i cea care face ca maparea s fie mai
dificil, i anume generarea id-urilor atunci cnd se face un insert. n Hibernate practic
trebuia mapat i o secven pentru generarea id-urilor. De asemenea, neplceri mai
apreau i dac se fceau insert-uri n sesiuni diferite de lucru,generarea secvenei
fcndu-se de la o valoare cu 50 mai mare fa de valoarea cu care s-a nceput sesiunea
precedent. Astfel, dac se fceau ntr-o sesiune de lucru mai mult de 50 de insert-uri
apreau probleme n sesiunea urmtoare deoarece se ncerca o inserare cu un id care
deja exista. Eu am ncercat ca prin simpla mapare cu o adnotare generarea s se fac
automat n raport cu valoarea maxim din tabel indiferent de sesiunea de lucru.
Descrierea proiectului
Proiectul presupune dezvoltarea unui mini sistem de mapare a obiectelor pe tabelele din
baza de date. Totui el trebuie s permit maparea obiectelor pe orice sistem de management al
bazelor de date relaionale, fr impunerea unui anumit sistem. Totodat, el trebuie s poat s
fac conversie ntre tipurile proprietilor din obiectele Java i tipul cmpurilor din tabele.
Acest mini ORM trebuie s implemeteze principalele operaii pe baza de date, cunoscute n
limbajul SQL ca: SELECT, DELETE, UPDATE, INSERT. Metodele asociate acestor operaii
sunt:
pentru SELECT
a) read(Object) aceast metod primete ca parametru un obiect al crui id este
cunoscut i returneaz din baza de date valorile cmpurilor pentru nregistrarea
cu id-ul id
b) readAll(Object) aceast metod primete ca parametru un obiect care
corespunde unui tabel din baz i returneaz toate nregistrarile din respectivul
tabel.
pentru DELETE
delete(Object) aceast metod primete ca parametru un obiect cu id cunoscut
i terge din baz nregistrarea din tabelul asociat obiectului, care are id-ul
id.Aceast metod nu returneaz nici un rezultat.
Pentru a demonstra avantajul sistemului este neesar realizarea unei aplicaii de test care
s permit tipuri de date multiple. Aceast aplicaie are ca tematic medicina i se ocup n
principiu de reete medicale, programri la doctor i vizualizarea acestora i este dezvoltat
folosind API-ul de SWT.
Alegerea Platformei
O platform este un mediu hardware sau software n care poate fi rulat un program.
Platforma aleas pentru dezvoltarea ORM-ului este platforma Java. Aceasta este o platform
software.
Alegerea acestei platforme se justific prin multitudinea de avantaje pe care le pune la
dispoziia dezvoltatorului:
este portabil,
Alte motive sunt reprezentate de faptul c limbajul Java este orientat obiect ceea ce permite
refolosirea codului i duce la micorarea semnificativ a dimensiunii codului, este robust i nu
n ultimul rnd este simplu de utilizat.
Platforma Java are dou componente:
a)
Maina virtual Java (Java Virtual Machine) Este componenta platformei care
face posibil neutralitatea fa de arhitectura folosit. La compilarea fiierelor .java ce conin
codul surs se creeaz nite fiiere cu extensia .class care conin secvene de bytecodes. Java
bytecodes reprezint instruciuni n limbaj main pentru JVM (Java Virtual Machine).
La stadiul actual instruciunile nu sunt nc destinate procesorului. Pentru a putea fi transformate
n cod neles de procesor este necesar o tranformarea din bytecodes n cod nativ al platformei
hardware prin intermediul Interpretorului integrat n structura JVM
Clas.java
Clas.class(
bytecodes)
Compilare
Cod main
JVM
b)
A doua component a platformei Java este API ul de Java (Application
Programming Interface) Acesta reprezint o colectie de librrii ce ajut la dezvoltarea mai
uoar a programelor. API-ul de Java este structurat n pachete, fiecare pachet nglobnd
metode, constante, parametri utilizai de ctre programatori n crearea obiectelor i structurilor
proprii.
10
n continuare voi dezvlui cteva avantaje ce justific alegerea unei astfel de platforme.
Ele sunt dup cum urmeaz:
a)
Simplitatea Java a fost proiectat s fie un limbaj simplu de utilizat i neles, el poate
fi asimilat cu usurin de ctre programatori, mai ales dac acetia au ceva experien si cu C++.
b)
Java este un limbaj orientat obiect Ofer un grad ridicat de abstractizare i ncapsulare.
Aest lucru duce la performane de securitate crescute, programatorul putnd face vizibile doar
informaiile pe care le dorete din interiorul obiectelor i folosind pentru acest lucru metode
dedicate accesrii informaiilor.
c)
Lucrul cu memoria este mult mbuntit, acest lucru datorndu-se n mare parte faptului
c nu mai exist pointeri definii de programator. Acetia erau o surs bogat de erori atunci
cnd se fcea accesul la memorie n C/C++. Limbajul introduce de asemenea un sistem automat
numit Garbage Collector care urmrete structura memoriei i observ obiectele neutilizate
urmnd s elibereze zona ocupat de respectivele obiecte i evitnd astfel fragmentarea
memorie.
d)
Principalul avantaj l reprezint portabilitatea. Un cod scris corect n limbajul Java ar
trebui s ruleze pe orice platform hardware fr nici o problem. Acesta reprezint un avantaj
major chiar i n faa unor limbaje care pot rula mai repede aa cum este C/C++. Este adevrat
c Java consum mai mult memorie i ruleaz ntr-un timp puin mai mare dect C/C++ dat
fiind faptul c este att un limbaj compilat ct i un limbaj interpretat. Totui n ziua de azi
diferenele nu mai sunt aa mari ca la nceputurile limbajului Java, iar portabilitatea limbajului
Java eclipseaz micul avantaj al C++. n cazul n care un program dezvoltat n C++ ar trebui
portat pe alt platform ar fi necesare modificri majore n cod.
n dezvoltarea ORM ului am ales platforma Java Standard Edition din cele trei platforme
oferite de Java, celelale dou fiind Java Micro Edition (platform destinat dispozitivelor
mobile aa cum sunt PDA uri sau telefoane mobile) i Java Enterprise Edition (platform
destinat sistemelor de calcul distribuite sau de mari dimensiuni), deoarece se preteaz cel mai
bine cerinelor proiectului fiind o platform specific aplicaiilor desktop.
Tehnologii folosite
cod, formatarea automat a codului i folosirea scurtturilor de taste pentru ndeplinirea mai
multor aciuni precum importuri de pachete necesare.
Cele mai folosite facilii din cele amintite mai sus sunt generarea automat a codului i
realizarea importurilor necesare. Generarea automat de cod se refer n general la generarea
de constructori cu sau fr parametri i generarea de getteri i setteri. Exist dou modaliti
de generare a getteri lor i setteri lor:
a) Din meniul Source se alege opiunea Generate Getters and Setters....
n fereastra deschis se pot alege cmpurile pentru care s se genereze getteri i
setteri.
12
13
API-uri folosite
n dezvoltarea acestui ORM am folosit patru API-uri: API-ul de JDBC oferit de
platforma Java, API-ul de Reflection, API-ul de SWT(Standard Widget Toolkit) i API-ul
pentru generarea de PDF-uri.
15
Statement care atunci cnd este folosit ncarc n memorie de fiecare dat
interogarea,
CallableStatement care este folosit atunci cnd se apeleaz proceduri stocate ale
bazei de date.
16
API-ul de Reflection
Reflection este o tehnologie ce permite studiul structurii unui obiect i modificarea
acesteia sau luarea de decizii n timpul rulrii pe baza structurii din acel moment a obiectului.
n Java API-ul de Reflection permite studierea clasei unui obiect, a cmpurilor
acestuia, a constructorilor, a metodelor din clas. Este posibil aflarea de informaii chiar i
despre cmpurile private.
Despre clase putem afla informaii cum ar fi adnotrile care sunt folosite pentru clasa
respectiv, numele clasei, cmpurile clasei, metodele acesteia, constructorii acesteia, pachetul
din care face parte i pachetele importate, interfeele pe care le implementeaz.
Despre constructorul unei clase putem afla parametrii pe care acesta i primete i
putem crea noi instane ale obiectului studiat prin apelul metodei newInstance(). Aceasta se
aplic pe obiectul de tip Constructor n care am reinut constructorul obiectului studiat. Aceast
metod primete ca parametri exact ce parametri primete i constructorul obiectului studiat.
Atunci cnd vrem s aflm informaii sau s manipulm cmpurile putem folosi
Reflection pentru a afla numele cmpurilor, adnotrile ce sunt folosite pentru cmpul studiat,
tipurile acestora i putem afla i modifica valorile acestora.
Pentru a afla informaiile despre cmpurile private este necesar s folosim metoda
getDeclaredFields().Aceasta, spre deosebire de metoda getFields() care ne va returna un vector
ce va conine doar cmpurile publice, ne va returna un vector cu toate cmpurile clasei inclusiv
cele private.
Despre metode putem afla parametri pe care aceasta i primete i tipul pe care aceasta
l returneaz. De asemenea cu ajutorul Reflection putem executa metode ale obiectului cu
ajutorul metodei invoke() care va primi ca parametri obiectul pentru care se execut metoda i
parametrii pe care aceasta i primete. Metoda invoke() va fi executat pentru obiectul de tip
Method n care am reinut metoda.
Mai putem afla informaii cum ar fii adnotrile prezente pe parametri funciilor sau ai
constructorilor, adnotrile de pe getteri i setteri.
17
18
unui element din palet n canvas, se va deschide automat o fereastr de proprieti din care
poate fi ajustat design-ul elementului respectiv.
19
Pentru a putea folosi SWT este necesar instalarea plug-in-ului mai nti deoarece
acesta nu este prezent n pachetul standard al Eclipse. Acest lucru se poate face foarte uor din
Eclipse din meniul Help opiunea Install New Software.... Plug-in-ul este gratuit i
opensource. Plug-in-ul este dezvoltat de IBM i de aceea nu vine mpreun cu API-ul standard
de java, n API-ul standard de Java putem gsi Swing i AWT, care sunt dezvoltate de compania
Sun, companie ce deine drepturile asupra Java.
Pentru a putea folosi mediul grafic de dezvoltare este necesar crearea unui tip de
clas ce poate fi gsit dup instalarea plug-in-ului. Crearea acestui tip de clas se face prin
click dreapta pe pachetul n care vrem s creem clasa, din meniul deschis alegem opiunea
New, iar din submeniul deschis vom alege opiunea Other. Din fereastra deschis vom
alege tipul de clas Application Window din folderul SWT aa cum vei vedea n imaginea
urmtoare.
f) de asemenea se poate scrie cu indici sau cu exponent sau se poate scrie textul
subliniat, tiat, boldat sau nclinat.
iText are elemente cu o structur ierarhic. Cea mai mic unitate din iText se numete
Chunk. Chunk-ul reprezint un String cruia i se poate seta doar fontul. Chunk-urile se pot
organiza n structuri mai mari i anume obiecte de tip Phrase.
Obiectele de tip Phrase permit definirea de spaiere. Pentru definirea mai multor
atribute cum ar fi cele de stil se folosesc obiecte de tip Paragraph. Acestea sunt obiecte ce
motenesc obiectele de tip Phrase.
O clas de obiecte ce motenete clasa Paragraph se numete Anchor i permite
definirea de referine de la anumite poriuni din text la alte poriuni mai ndeprtate sau la care
se face referire n text. Obiectele de tip Paragraph se pot grupa n structuri de tip Chapter.
n iText mai putem ntlni obiecte de tip Section pentru definirea unei seciuni, List
pentru realizarea de liste ordonate sau neordonate, obiecte de tip Font penru definirea de fonturi.
Dezvoltarea aplicaiei
Aplicaia dezvoltat este reprezentat de un mini sistem de mapare a obiectelor din Java
pe tabelele unei baze de date, sistem denumit Object-Relational Mapping.
Cerinele aplicaiei
Scopul acestei lucrri l reprezint dezvoltarea unui sistem ORM care s fie uor de
folosit i neles.
Obiectivele acesti proiect sunt reprezentate de implementarea operaiilor uzuale de
INSERT, UPDATE, DELETE, SELECT, iar mai apoi s poat fi folosite fr a mai scrie cod
SQL. Un alt obiectiv l reprezint funcionarea ORM-ului pe baza unor relaii stabilite ntre
obiectele din Java i tabelele din baza de date. Aceste relaii se pot stabili fie prin folosirea
adnotrilor fie prin folosirea unor fiiere de configurare de tip properties sau xml. n aceast
lucrare am ales s folosesc varianta cu adnotri deoarece este varianta mai modern i care a
ctigat teren n faa celei de-a doua n ultimii ani. De asemenea varianta cu asdnotri este dup
prerea mea mai simplu de neles i mai intuitiv.
Dup definirea relaiilor dintre obiecte i tabele se vor folosi doar obiectele i metodele
implementate n ORM. ORM-ul trebuie s dispun de urmtoarele metode:
a) read(object) citete toate cmpurile obiectului specificat din care iniial
este cunoscut doar id-ul
b)
c)
doar id-ul
vreo
clauz WHERE
21
Arhitectura
Noiunea de arhitectur software se refer la componentele de nivel nalt ale unui
sistem software. Arhitectura definete att modulele sistemului pe baza unui set de reguli i
relaiile care se stabilesc ntre acestea, ct i proprietile pe care modulele i relaiile dintre ele
le dein.
La cazul general, o arhitectur pentru un sistem software se compune din:
Component de comunicaie cu exteriorul
Component ce se ocup de logica de business a aplicaiei
Component responsabil cu pstrarea datelor
Componenta de comunicaie cu exteriorul poate fi reprezentat n funcie de tipul
aplicaiei de pagini web, interfee grafice desktop .a. Prin intermediul acesteia utilizatorul
introduce date n sistem sau preia date din sistem.
Componenta responsabil cu prelucrarea informaiilor provenite de la utilizator sau a
informaiilor ce i vor fi returnate acestuia este componenta de logic de business i reprezint
partea central a aplicaiei. Toate datele care circul prin sistem sunt ntotdeauna filtrate de
aceast component.
Componenta responsabil de pstrarea informaiilor n sistem este reprezentat de un
sistem de management al bazelor de date. Aceasta permite salvarea unei cantiti mari de date,
preluarea datelor , actualizarea sau tergerea acestora.
O astfel de arhitectur am folosit i n dezvoltarea i testarea proiectului de fa. n
cazul acestui proiect am considerat pentru componenta de baze de date cele mai utilizate dou
sisteme de management ale bazelor de date,PostgreSQL i Microsoft SQL Server.
Componenta care se ocup de comunicaia cu exteriorul este reprezentat aici de o
aplicaie grafic n care utlizatorul interacioneaz cu restul aplicaiei prin intermediul unor
formulare. Totui, aceast component poate fi reprezentat la fel de bine de orice alt aplicaie
ce folosete o conexiune la baza de date.
Componenta de logic de business este reprezentat aici de ORM. Sistemul ORM
funcioneaz ca o legtur ntre aplicaie i baza de date. Prin intermediul lui se preiau datele de
la aplicaia grafic, pe care mai apoi le folosim pentru a accesa baza de date.Totodat el permite
salvarea informaiilor introduse prin aplicaie n baza de date sau poate extrage informaii din
baz n funcie de aciunile fcute de utilizator. Dup preluarea datelor, ORMul, le prelucreaz
i le face disponibile pentru aplicaie.
n imaginea de urmtoare am ilustrat arhitectura unui sistem complet din viaa real
22
Sistem Object-Relational
Mapping
Baz de date
(PostgreSQL,
Microsoft Server
SQL, etc.)
Aplicaie , Interfa cu
utilizatorul
Strucura proiectului
Codul proiectului este organizat pe pachete n funcie de funcionalitile pe care le
ofer.
23
Acest pachet mpreun cu pachetul de queryactions reprezint centrul propriu zis aplicaiei
i ocupndu-se de ceea ce nseamn un orm.
Pachetul org.licenta.aplicatie.model conine clasele model folosite pentru testarea ormului dezvoltat:
1.
2.
3.
4.
5.
driver = org.postgresql.Driver
url = jdbc:postgresql://localhost:5432/
databaseName = aplicatie
userName = alin
userPassword = iomanigar
1. try {
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
if
(driverName.equals("com.microsoft.sqlserver.jdbc.SQLServerD
river")){
String con
=url+";databaseName="+databaseName+";user="+usrName+
";password="+usrPass;
connection = DriverManager.getConnection(con);
} else {
connection =
DriverManager.getConnection(url+databaseName,usrName,
usrPass);
}
} catch (SQLException e) {
System.out.println("Conectarea nu a reusit!");
}
poate observa n cazul Microsoft conectarea se face folosind un singur parametru ce conine
toate datele de logare pe cnd la restul SGBD-urilor conectarea se face folosind trei parametri.
n cazul n care conexiunea nu s-a fcut cu succes se va primi un mesaj corespunztor. O alt
parte important sistemului este implementarea celor patru operaii: read(object),
readAll(bbject), delete(object), save(object).
Metoda read(Object) trebuie s citeasc toate cmpurile obiectului specificat din care
iniial se cunoate doar id-ul. Aceast metod, pe lng studierea clasei cu ajutorul API-ului de
Reflection, se folosete de metoda read(Long) din clasa QueryActions ce returneaz un
HashMap(conine nregistrari de forma cheie=valoare) n care cheia este numele coloanei din
tabel i valoarea este valoarea ce o are nregistrarea cutat n tabel. Pentru implementarea
acestei metode am folosit API-ul de JDBC.
Clasa QueryActions are ca i cmp o variabila de tip String creia i se asigneaz o
valoare la instanierea unui obiect de tip QueryActions prin constructor.
Pentru maparea clasei pe tabel am folosit o adnotare denumit @Table. Aceasta
primete ca parametru un String ce reprezint numele tabelului. O parte foarte important a
27
7.
8.
9.
return tableName;
}
Secvena 4.3. Extragerea unei adnotri prezent pe clas i studierea parametrului acesteia
n liniile de cod de mai sus se afl o metod ce studiaz dac asupra clasei se afla
adnotri. La linia patru se poate observa c se extrag doar adnotrile de tip Table iar la linia ase
se extrage numele tabelului ce va fi folosit mai departe.
O alt metod folosit n metoda read este metoda getId. Aceasta extrage pe baza
adnotrii @PK id-ul obiectului. Adnotarea @PK este folosit pentru a mapa cheia un cmp din
clas pe cheia primar din tabel. n rndurile urmtoare se poate vedea modalitatea de extragere
a valorii id-ului.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
if (annot instanceof PK
&& field.getType().getSimpleName().equals("Long"))
{
try {
id = (Long) field.get(object);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return id;
n liniile de mai sus se verific dou condiii necesare pentru a stabili dac un cmp
este mapat corect pe cheia primar din tabel i anume s dispun de o adnotare de tip @PK si
s fie de tipul Long. Verificarea tipului este necesar deoarece tabele pot ajunge la dimensiuni
foarte mari, iar tipul Long ofer o gam de valori suficient de mare pentru a permite un numr
mare de nregistrri.
n metoda read(object) primi pai sunt reprezentai de folosirea celor dou metode mai
sus menionate pentru a afla numele tabelului pe care este mapat clasa i id-ul obiectului.
Numele tabelului va fi folosit pentru a instania un obiect de tip QueryActions iar id-ul pentru
28
a extrage din baza de date nregistrarea cu id-ul dat ca parametru. Asignarea de valori cmpurilor
obiectului se face pe baza cheii din HashMap-ul rezultat n urma aplicrii metodei read(Long).
Maparea Cmpurilor din obiect pe coloanele tabelului se face cu ajutorul adnotrii
@Column ce primete ca parametru numele coloanei.Maparea se poate face i pe baza numelui
cmpului dac numele acestuia este acelai cu numele coloanei din baza de date. Mai jos putei
vedea liniile de cod prin care se face maparea efectiv.
1.2.
if ( annots. length
3.4.
5.6.
Column ) {
== 0) colName = field.getName();{
} else {
for
7.8.
9.
10.
11.
12.
13.
14.
15.
colName = field.getName();
}
}
}
Variabila annots din codul de mai sus reprezint vectorul ce conine adnotrile unui
cmp.
Adnotarea @NotPersistent ce apare n cod este folosit pentru cmpurile ce nu vor fi
folosite pentru persistena n baza de date.
Urmtoarea metod implementat este readAll(object). Spre deosebire de metoda
anterioar, aceasta nu folosete metoda getId deoarece scopul ei este s citeasc toata obiecte
de tipul celui specificat, i nu unul anume. O metod nou folosit in dezvoltarea acesteia este
metoda getColumns din clasa QueryActions.
Metoda getColumns returneaz o list de String-uri ce reprezint numele coloanelor
exact n ordinea n care acestea se gsesc n tabel. Aceast metod este util deoarece pe baza
rezultatului returnat vom putea asigna valori cmpurilor din obiecte indiferent de ordinea n
care acestea sunt declarate. Astfel programatorul nu va fi obligat s tie exact ordinea coloanelor
din baza de date. O alt utilitate a acestei metode este i faptul c putem extrage din lista
rezultat numele coloanei ce conine id-ul, acest lucru fiind necesar deoarece maparea cmpului
pentru id se face doar cu adnotarea @PK, nespecificnd numele coloanei cu id-ul nicieri n
29
clasa noastr. n metoda readAll(object) am folosit aceast metod pentru cea de-a doua
utilitate. Metoda getColumns a fost implementat cu ajutorul JDBC.
1.
2.
3.
4.
5.
6.
try {
Object firstKey = columns.get(0);
field.set(inst, help.get(i).get(firstKey));
} catch (IllegalArgumentException|IllegalAccessException e) {
e.printStackTrace();
}
...
30
if (a instanceof Column) {
Column col = (Column) a;
colName = col.name();
pos = coloane.indexOf(colName) - 1;
}
...
n liniile de cod de mai sus se afl un exemplu de aflare a poziiei unei coloane n tabel.
Variabila pos reprezint poziia pe care va fi pus valoarea cmpului obiectului n lista de valori
ce va fi trimis ca parametru metodei save din QueryActions. n metoda save(object) formm
din cmpurile obiectului dat ca parametru lista de valori necesar metodei save(Long, List<
Object >).
n rndurile urmtoare voi vorbi despre metoda save(Long, List< Object >) din clasa
QueryActions. n aceast metod se folosesc alte dou metode implementate n aceeai clas:
update(Long, List< Object >) i metoda insert(List< Object >).
n aceste dou metode partea cea mai dificil i cea mai important a fost formarea
interogrii. O atenie special au necesitat obiectele de tip String i cele de tip Date.
Obiectele de tip String au valori ce sunt ncadrate ntre ghilimele i nu toate sistemele
de gestiune a bazelor de date relaionale accept valori ncadrate ntre ghilimele, ns absolut
toate accept ncadrarea ntre apostrof. n liniile de cod urmtoare se va vedea cum am nlocuit
ghilimelele cu apostrof n cazul metodei update i cum am format interogarea, aceasta trebuind
s se formeze corect indiferent de numrul de elemente ale listei dat ca parametru.
31
1.
2.
3.
4.
5.
6.
7.
8.
if (valori.get(i).getClass().getName().equals("java.lang.String")) {
help += coloane.get(i) + "=" + "\'" + valori.get(i)+ "\', ";
} else if (valori.get(i).getClass().getName().equals("java.util.Date"))
{
java.sql.Date data =
new Date(((java.util.Date)
valori.get(i)).getTime());
help += coloane.get(i) + "=" + "\'" + data + "\', ";
} else {
help += coloane.get(i) + "=" + valori.get(i) + ", ";
}
Dup cum se poate observa obiectele de tip Date trebuie convertite la un alt tip de
obiect Date care s fie compatibil cu cel din baza de date. De asemenea i valorile unor
asemenea obiecte trebuie ncadrate cu apostrof. Diferena la metoda insert era c nu se adaug
iruri de caractere de forma nume_coloan=valoare, ci dup valoare se pune caracterul virgul.
n ambele metode mai trebuie fcut o verificare, i anume dac valoarea se afl pe
ultima poziie n lista de valori, formarea interogrii fiind puin diferit.
1.if(valori.get(i).getClass().getName().equals("java.lang.String"
2.
)){
3.
help += coloane.get(i) +
"=" + "\'" + valori.get(i)
4.
+ "\' WHERE " + idTabel +
"=" + id;
5.
} else if
(valori.get(i).getClass().g
etName()
6.
.equals("java.util.Date")){
7.
java.sql.Date data = new
8.
Date(((java.util.Date)valor
i.get(i)).getTime());
9.
help += coloane.get(i) +
"=" + "\'" + data + "\'
WHERE "
10.
+ idTabel + "=" +id;
11.
12. }
1.
2.
3.
4.
5.
6.
7.
8.
if(lista.get(i).getClass().getName().equals("java.lang.String"
)) {
help += "\'" + lista.get(i) + "\') ";
} else if
(lista.get(i).getClass().getName().equals("java.util.Date")) {
java.sql.Date data = new
Date(((java.util.Date)lista.get(i)).getTime());
help += "\'" + data + "\') "; 9. }
32
Secvenele de cod de mai sus ilustreaz modul n care se formeaz interogarea pentru
ultima valoare din list. Dupa cum se poate observa n prima secven(extras din metoda
update) dup ultima valoare urmeaz caluz WHERE pe cnd n cazul metodei insert , ilustrat
n cea de-a doua secven de cod, dup ultima valoare urmeaz nchiderea unei paranteze.
n cazul metodelor din clasa ORMHandler, i anume read(object), readAll(object),
delete(object), save(object), am implementat astfel nct acestea s accepte orice tip de obiect.
Acest lucru a fost realizat fcnd ca aceste patru metode s fie generice, astfel ele putnd accepta
orice tip de obiect.
Aa cum se poate observa n secvena de mai sus la toate cele patru metode este prezent
parametrul care devine tipul obiectului dat ca parametru. Acest lucru face ca metodele s
accepte ca parametru orice tip de obiect. Atunci cnd metodele sunt folosite nu este nevoie de
vreun apel special de metod, se va apela pur i simplu prin numele metodei i i se va da ca
parametru orice tip de obiect se dorete. Mai jos voi ilustra apelul unei astfel de metode.
1.
2.
3.
4.
Dup cum se poate observa faptul c metoda read(object) este una generic nu
complic deloc folosirea ei.
Prima problem ce apare la maparea cheii primare este compatibilitatea numelui
cmpului sau cum putem indica ct mai simplu faptul c un cmp este corespondentul cheii
primare din tabel. n rezolvarea acestei probleme am plecat de la considerentul c pentru un
tabel prima coloan va fi tot timpul reprezentat de cheia primar.
33
Mai sus se afl una din secvenele de cod ce rezolv aceast problem. Executarea
interogrii din prima linie duce la reinerea tuturor datelor despre tabel n variabila helpRs.
Extragerea metadatelor se face cu metoda getMetaData(). Metadatele reprezint numele
coloanelor, tipurile acestora, numrul coloanelor etc. Metoda getColumnName(1) returneaz
numele primei coloane din tabel, adic cea care conine cheia primar. Menionez c metoda
getMetaData returnez coloanele exact n ordinea n care ele se gesc n tabel.
O alt metod de rezolvare folosit n implementarea sistemului este reinerea tuturor
numelor coloanelor ntr-o list i folosirea primului element din list atunci cnd avem nevoie
de coloana pentru cheia primar. Acest lucru se realizeaza cu ajutorul metodei getColumns din
clasa QueryActions.
1.
2.
try {
for (int i = 1; i <
rsmd.getColumnCount() + 1; i++)
3.
rez.add(rsmd.getColumnName(i));
4.} catch (SQLException e) {
5.
e.printStackTrace();
6.
}
Adugarea acestei secvene de cod la secvena de mai devreme duce la formarea unei
liste cu numele coloanelor.
Un exemplu de folosire a celei de-a doua metode poate fi observat n metoa readAll.
Mai jos se afl secvena de cod ce ilustreaza folosirea celei de-a doua metode.
1.
2.
3.
4.
5.
6.
7.
8.
try {
Object firstKey = columns.get(0);
field.set(inst, help.get(i).get(firstKey)
} catch (IllegalArgumentException|
IllegalAccessException e) {
e.printStackTrace()
}
}
34
cod de mai sus columns reprezint lista cu numele coloanelor dintr-un tabel. Numele primei
coloane este extras i este folosit pentru a se extrage valoarea cheii primare dintr-un HashMap
ce conine nregistrri de tip cheie=valoare, cheia fiind numele coloanei.
Cea de-a doua problem la maparea cheii primare este generarea id-ului. Aceast
problem a fost rezolvat innd cont doar de valoarea maxim a id-ului la un moment de timp.
Nu s-a inut cont de valoarea id-ului din sesiunile anterioare.
5.6.
resultSet = helpStmt.executeQuery(helpQuery);while
(resultSet.next()) {
7.8.
idRow)
9.
10.
12.
13.
14.
15.
16.
n liniile de mai sus se poate observa c este extras valoarea maxim a cheii primare
din tabel. La final valoarea maxim este incrementat, astfel asigurnd unicitatea cheii primare.
Dac n tabel nu exist nregistrri nu reprezint o problema deoarece valoarea este iniializat
cu 0 i este incrementat oricum la final, fie c a gsit valori sau nu n tabel.
Rezolvarea celei de-a doua probleme a fost mai facil deoarece pentru maparea oricrui
tip de dat ce conine caractere am folosit direct clasa String. n Hibernate atunci cnd se preiau
date din baza de date sunt salvate ntr-un array ce conine date de tip char. Apoi fcndu-se castul la String dac este nevoie. De asemenea atunci cnd se salveaz un ir de caractere n baza
de date acestea sunt convertite n array de char-uri si pentru acest lucru este nevoia de
specificarea lungimii dac acesta depete 255.
O alt parte a acestei lucrri ce a rmas neatins sunt adnotrile. Acestea reprezint
metadate ce pot fi adugate claselor, pachetelor, cmpurilor. Sunt caraterizate de prezena
caracterului @ la nceput. Spre deosebire de comentarii ele sunt recunoscute de compilator i
35
apar ca elemente i in API-ul de Reflection. Aici am folosit adnotri pentru maparea claselor i
cmpurilor pe tabele i coloane. Ele pot conine parametrii care de asemenea sunt cunoscui i
pot fi utilizai n cercetarea claselor i a cmpurilor. Pentru mapare am folosit urmtoarele
adnotri:
a) @Table aceasta poate primete ca parametru numele tabelului e care
se mapeaz
clasa. Implementarea adnotrii poate fi observat ma jos.
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String name();
}
Adnotarea @Retention este folosit pentru a specifica momentul cnd s fie luat n
considerare adnotarea. Pentru toate adnotrile implementate am ales s fie active la rulare
@PK am folosit-o pentru a mapa cheia primar
b)
@Retention(RetentionPolicy.RUN
TIME)
public @interface PK {
}
37
Concluzii
Un ORM este o soluie viabil pentru programatori atunci cnd doresc s mbine
programarea orientat-obiect cu lucrul cu baze date deoarece este un sistem scalabil, rapid i
uor de folosit.
Un astfel de sistem poate duce la creare de aplicaii stabile ntr-un timp mult mai scurt.
De asemenea duce la scrierea unui cod uor de ntreinut i depanat deoarece reduce cantitatea
de cod i este i uor de neles.
Cea mai bun metod de mapare a obiectelor pe tabele este folosirea adnotrilor
deoarece este o metod mai intuitiv i care nu necesit crearea unor fiiere de configurare mari
i greu de urmrit.
Pentru dezvoltarea unui sistem de mapare a obiectelor pe tabelele dintr-o baz de date
este necesar folosirea att a API-ului de JDBC ct i a API-ului de Reflection.
Acest ORM ncearc s trateze unele probleme a cror rezolvare ar duce la o utilizare
mai uoar i la o funcionare mai aproape de ceea ce se ateapt un programator.
Un astfel de sistem poate fi folosit la implementarea modelului i chiar a unei pri din
controller din pattern-ul de proiectare MVC(Model-View-Controller), care este una din cele
mai utilizate metode la dezvoltarea aplicaiilor att desktop ct i web.
Bibliografie
[1] Tanasa Stefan, Andrei Stefan, Olaru Cristian, 2007. Java de la 0 la
Expert Ediia a II-a revizuit. POLIROM, Iai
[2] Roland Barcia, Geoffrey Hambrick, Kyle Brown, Robert Peterson,
Kulvir Singh
Bhoga. 2008. Persistence in the Enterprise: A Guide to Persistence Technologies. IBM
Press, Boston
[3]Jakob Jenkov. Java Reflection Tutorial. http://tutorials.jenkov.com/javareflection/index.html, accesat la data de 13.06.2013
[4]Jakob
Jenkov.
Java PDF Generation
with
http://tutorials.jenkov.com/java-itext/index.html, accesat la data de 23.06.2013
IText.
[5]Lars Vogel. 2010. Creating PDF with Java and iText - Tutorial.
http://www.vogella.com/articles/JavaPDF/article.html, accesat la date de 23.06.2013
[6]Oracle
Java SE
Documentation,
Annotations.
http://docs.oracle.com/javase/6/docs/technotes/guides/language/annotations.html, accesat la
data de 28.05.2013
38
[8]Hibernate Documentation.
2013 Hibernate
Developer
Guide.
http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/, accesat la data de 30.05.2013
[9] Bitcell. 2009. Tutoriale Java. http://www.bitcell.info/tutorial-java-introduceredespre-platforma-t674.html, accesat a data de 29.06.2013
[10]Eclipse. 2013. SWT
The Standard
http://www.eclipse.org/swt/, accesat la data de 20.06.2013
Widget
Toolkit.
39