programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/pbp19/pbp.pdf · glava 2. nacini koriˇ...

141
Programiranje baza podataka Beleˇ ske za predavanja Autor materijala: Vesna Marinkovi´ c email: [email protected] URL: www.matf.bg.ac.rs/ ~ vesnap Matematiˇ cki fakultet, Beograd Izmene za ˇ skolsku 2018/2019. godinu dodaje: Nina Radojiˇ ci´ c Mati´ c email: [email protected] URL: www.matf.bg.ac.rs/ ~ nina Matematiˇ cki fakultet, Beograd c 2016 1

Upload: others

Post on 16-Aug-2020

18 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Programiranje baza podatakaBeleske za predavanja

Autor materijala:Vesna Marinkovic

email: [email protected]: www.matf.bg.ac.rs/~vesnap

Matematicki fakultet, Beograd

Izmene za skolsku 2018/2019. godinu dodaje:Nina Radojicic Matic

email: [email protected]: www.matf.bg.ac.rs/~nina

Matematicki fakultet, Beograd

c©2016

1

Page 2: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2

Autor:dr Vesna Marinkovic, docent Matematickog fakulteta u Beogradu

PROGRAMIRANJE BAZA PODATAKA

Sva prava zadrzana. Nijedan deo ovog materijala ne moze biti reprodukovan nitismesten u sistem za pretrazivanje ili transmitovanje u bilo kom obliku, elektronski,mehanicki, fotokopiranjem, smanjenjem ili na drugi nacin, bez prethodne pismenedozvole autora.

Page 3: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Sadrzaj

Sadrzaj 3

1 Uvod 51.1 Logistika kursa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Nacini koriscenja baza podataka u visim programskim jezicima 72.1 Aplikativni (ugradeni) SQL . . . . . . . . . . . . . . . . . . . . . 82.2 Dinamicki SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.3 Direktni pozivi funkcija SUBP (CLI) . . . . . . . . . . . . . . . . 262.4 Upotreba ODBC standarda . . . . . . . . . . . . . . . . . . . . . 332.5 Zapamcene procedure . . . . . . . . . . . . . . . . . . . . . . . . 38

3 Transakcije 473.1 Transakcija i integritet . . . . . . . . . . . . . . . . . . . . . . . . 473.2 Konkurentnost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.3 Osobine transakcija i nivoi izolovanosti transakcija . . . . . . . . 553.4 Oporavak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623.5 Katanci i zakljucavanje – prosirenje . . . . . . . . . . . . . . . . . 69

4 Objektno-relaciono preslikavanje i alat Hibernate 774.1 Objektno-relaciono preslikavanje . . . . . . . . . . . . . . . . . . 784.2 Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

5 Administracija baza podataka 1295.1 Kreiranje baze podataka . . . . . . . . . . . . . . . . . . . . . . . 1295.2 Pravljenje rezervnih kopija i oporavak . . . . . . . . . . . . . . . 1375.3 Aktivnosti na odrzavanju baze podataka . . . . . . . . . . . . . 140

3

Page 4: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se
Page 5: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Glava 1

Uvod

1.1 Logistika kursa

Cilj kursa:

• usvojiti napredne koncepte i tehnike baza podataka,

• savladati aplikativni SQL (SQL/C, SQL/Java),

• savladati ODBC standard rada sa bazom podataka (JDBC),

• ovladati tehnikama programiranja transakcija (upravljanje transakcijama,pad i oporavak; kontrola konkurentnosti),

• shvatiti osnove objektno-relacionog preslikavanja (ORM Hibernate),

• dobiti pregled operacija potrebnih za administraciju i odrzavanje bazepodataka.

Literatura:

• G. Pavlovic - Lazetic: Osnove relacionih baza podataka, Matematickifakultet, Beograd, 1999.

• H. Garcia-Molina, J. D. Ullman, J. Widom: Database Systems: The Com-plete Book, International Version, 2nd edition, Pearson Education, 2008.

• C.J.Date: An Introduction to Database Systems, VIII ed, Addison WesleyInc, 2004.

• S. Malkov: Programiranje baza podataka, skripta

• DB2 uputstva i materijali

5

Page 6: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

6 GLAVA 1. UVOD

Obaveze na kursu u 2018/19 godini:

• kolokvijum od 20 poena (prag od 5 poena)

• jedan teorijski test od 10 poena (radi se na casu predavanja)

• pismeni ispit od 40 poena

• zavrsni teorijski ispit od 30 poena

Da bi se pristupilo polaganju zavrsnog teorijskog ispita potrebno je imatibar 25 poena u zbiru na pismenom ispitu i kolokvijumu.

Da bi se polozio ispit potrebno je imati i bar 20 poena u zbiru na teorijskomtestu i zavrsnom teorijskom ispitu.

Page 7: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Glava 2

Nacini koriscenja baza podataka uvisim programskim jezicima

Vecina SQL proizvoda podrzava dva vida izvrsavanja SQL naredbi:

• interaktivni, koji podrazumeva izvrsavanje samostalnih SQL naredbipreko on-line terminala,

• aplikativni, koji podrazumeva izvrsavanje SQL naredbi umetnutih uprogram na visem programskom jeziku, pri cemu se SQL naredbe moguizvrsavati naizmenicno sa naredbama programskog jezika.

Program na aplikativnom SQL-u prolazi kroz pretprocesiranje kao prvufazu svoje obrade. Aplikativni SQL moze da ukljuci dve vrste SQL naredbi:

• staticke SQL naredbe koje vec u fazi pisanja programa imaju precizanoblik i cija se analiza i priprema za izvrsenje mogu u potpunosti obavitiu fazi pretprocesiranja;

• dinamicke SQL naredbe koje se zadaju u obliku niske karaktera kojase dodeljuje promenljivoj u programu; analiza i priprema ovakve vrstenaredbi moze se obaviti tek u fazi izvrsavanja programa kada je poznatnjen precizni oblik.

Pored ovakvog nacina koriscenja baze podataka u programu na program-skom jeziku, postoje i druge mogucnosti ugradnje blokova za komunikacijusa SUBP u program. U slucaju sistema DB2, to su:

• direktni pozivi DB2 funkcija (engl. Call Level Interface - CLI) i

• upotreba ODBC standarda (engl. Open DataBase Connectivity).

ODBC standard podrazumeva sledeci model komunikacije: korisnik ko-municira sa ODBC medusistemom, koji dalje komunicira sa konkretnim SUBP-om, potpuno nezavisno od korisnika. U ovom modelu podrazumeva se stan-dardizovanje komunikacije korisnika sa ODBC medusistemom, nezavisno odSUBP kome ce medusistem proslediti zahtev korisnika. Na ovaj nacin je koris-niku olaksan posao jer pise program na isti nacin bez obzira na to nad kojim

7

Page 8: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

8GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

SUBP-om radi, ali nije moguce iskoristiti specificnosti pojedinog sistema (uovom slucaju sistema DB2). Svi upiti upuceni sistemu DB2 preko ODBC stan-darda izvrsavaju se dinamicki.

S druge strane, direktni pozivi DB2 funkcija su specificni za DB2 sistemi koriste sve njegove mogucnosti (kao i aplikativni SQL), s tim da je ipakovaj pristup izgraden tako da ima najveci moguci zajednicki skup funkcijai principa sa ODBC pristupom, cime je korisnicima omoguceno da ukoliko jepotrebno jednostavnije prilagodavaju programe jednom ili drugom obliku.

Ugradeni SQL je po mogucnostima slican CLI sistemu, jedina bitna raz-lika je u nacinu kodiranja SQL naredbi. Dok se u CLI pristupu podrazumevaupotreba funkcija kojima se kao argumenti zadaju SQL naredbe, u ugradenomSQL-u se koriste makroi za kodiranje SQL naredbi. Ugradeni SQL se prevodi,od strane pretprocesora, u program koji ne sadrzi makroe, vec CLI pozive.

Za razliku od programa na aplikativnom SQL-u koji mora da se pretpro-cesira, prevede, poveze sa bazom i najzad izvrsi, DB2 CLI aplikacija ne morani da se pretprocesira ni da se povezuje sa bazom; ona koristi standardni skupfunkcija za izvrsavanje SQL naredbi u vreme izvrsavanja programa. Osnovnaprednost aplikativnog SQL-a u odnosu na direktne pozive DB2 funkcija jeu tome sto moze da koristi staticki SQL i sto je u velikoj meri standardizo-van pa se moze koristiti (u manjoj ili vecoj meri) i medu razlicitim SUBP-platformama.

U slucaju da aplikacija zahteva prednosti oba mehanizma (DB2 CLI i ap-likativnog SQL-a), moguce je koristiti staticki SQL unutar DB2 CLI aplikacijekreiranjem zapamcenih procedura (engl. stored procedures) napisanih nastatickom SQL-u. Zapamcena procedura se poziva iz DB2 CLI aplikacije iizvrsava se na serveru. Jednom napisanu zapamcenu proceduru moze da po-zove bilo koja DB2 CLI ili ODBC aplikacija. Naime, aplikacija moze biti is-projektovana tako da se izvrsava u dva dela: jedan deo na klijentu, a drugi naserveru, pri cemu je zapamcena procedura deo koji se izvrsava na serveru.

2.1 Aplikativni (ugradeni) SQL

Moze se polemisati o tome da li je pozeljnije koristiti samo jedan jezik: da sesve odradi u SQL-u ili da zaboravimo SQL i sve racunamo u nekom visemprogramskom jeziku. Medutim, potreba za umetanjem SQL-a u visi pro-gramski jezik javlja se zbog odsustva kontrolnih struktura u upitnom jeziku,cesto neophodnih pri obradi podataka iz baze podataka. S druge strane, SQLznacajno pomaze programeru u pisanju operacija nad bazom podataka: naovaj nacin operacije nad bazom se efikasno izvrsavaju i, dodatno, izrazene suna visem nivou. Umetanjem (tzv. ugnjezdenjem) SQL-a (engl. EmbeddedSQL) u visi programski jezik, tzv. maticni jezik (engl. host language), kaosto su npr. C, Java, FORTRAN, COBOL ili Pascal, dobija se aplikativni SQL,na kome se mogu pisati kompleksni programi za najraznovrsnije obrade. Os-novni princip svih aplikativnih SQL jezika je princip dualnosti, prema komese svaka interaktivna SQL naredba moze izraziti i u aplikativnom SQL-u, aliobratno ne vazi (sto i opravdava ovakva umetanja).

Osnovni problem pri povezivanju SQL naredbi sa onima u standardnimprogramskim jezicima jeste cinjenica da se model podataka u SQL-u razlikujeod modela podataka u drugim jezicima. Kao sto je poznato, SQL koristi rela-

Page 9: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.1. APLIKATIVNI (UGRAÐENI) SQL 9

cioni model podataka, dok recimo C i slicni jezici koriste model podataka kojiukljucuje cele brojeve, razlomljene brojeve, karaktere, pokazivace, strukturepodataka, nizove itd. Skupovi nisu direktno podrzani u jeziku C, dok SQLne koristi pokazivace, petlje, grananja i mnoge druge uobicajene programskekonstrukcije. Dakle, razmena podataka izmedu SQL-a i drugih program-skih jezika nije pravolinijska i potrebno je definisati mehanizam kojim bi seomogucio razvoj aplikacija koje koriste i SQL i neki drugi programski jezik.

Svi dalji koncepti aplikativnog SQL-a bice ilustrovani na primeru tabeleKnjiga koja je definisana na sledeci nacin:

create table Knjiga

(k_sifra integer not null,

naziv char(50) not null,

izdavac char(30),

god_izdavanja smallint,

primary key (k_sifra))

Povezivanje SQL-a sa maticnim jezikom

Kada zelimo da koristimo SQL naredbu u programu na maticnom jeziku, up-ozoravamo pretprocesor da nailazi SQL kod navodenjem kljucnih reci EXECSQL ispred naredbe. Informacije se razmenjuju izmedu baze podataka, kojojse pristupa samo preko SQL naredbi, i programa na maticnom jeziku krozhost (maticne) promenljive (engl. host variables), za koje je dozvoljeno da sepojave i u naredbama maticnog jezika i u SQL naredbama. Host promenljiveimaju kao prefiks dvotacku u naredbama SQL-a, dok se u naredbama maticnogjezika javljaju bez dvotacke.

Program koji sadrzi izvrsne SQL naredbe komunicira sa sistemom DB2preko memorijskog prostora koji se zove SQL prostor za komunikaciju (engl.SQL Communication Area, SQLCA). SQLCA je struktura podataka koja seazurira posle izvrsavanja svake SQL naredbe. U ovu strukturu upisuju seinformacije o izvrsenoj SQL naredbi.

SQLCA prostor se u program na maticnom jeziku ukljucuje naredbom:

EXEC SQL INCLUDE SQLCA;

Ovde je u pitanju SQL naredba INCLUDE. Ova komanda se razlikuje odstandardne pretprocesorske direktive #include po tome sto se izvrsava prepretprocesiranja od strane SQL pretprocesora, a #include se izvrsava tek kas-nije, pri prevodenju programa na maticnom jeziku. Ova naredba se moranavesti pre prve izvrsne SQL naredbe. Jedan od efekata ove naredbe jestedeklaracija SQLCA strukture, koja se koristi za obradu greske.

Najcesce koriscena promenljiva strukture SQLCA je promenljiva SQLCODE.Ona predstavlja indikator uspesnosti izvrsenja SQL naredbe i moze da imasledece vrednosti:

• 0, ako je izvrsavanje proslo uspesno (ako je pritom vrednost promenljiveSQLWARN0=” onda je sve u redu, ako je SQLWARN0=’W’ znaci da sejavilo neko upozorenje),

• pozitivnu vrednost, ako se pri uspesnom izvrsavanju dogodilo nesto i-zuzetno (npr. +100 ako je rezultujuca tabela prazna),

Page 10: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

10GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

• negativnu vrednost, ako se zbog nastale greske naredba nije izvrsilauspesno.

Provera statusa izvrsenja SQL naredbe, sacuvane u promenljivoj SQLCODE,zadaje se direktivom pretprocesoru da umetne odgovarajuce IF - THEN na-redbe u program. Direktiva je deklarativni iskaz oblika:

EXEC SQL WHENEVER <uslov> <akcija>;

pri cemu <uslov> moze biti:

• NOT FOUND (nije naden - drugi zapis za SQLCODE = 100),

• SQLERROR (indikator greske - drugi zapis za SQLCODE < 0) ili

• SQLWARNING (indikator upozorenja - drugi zapis za SQLWARN0 = ’W’ OR

(SQLCODE > 0 AND SQLCODE <> 100));

a <akcija> je:

• CONTINUE - program nastavlja sa izvrsenjem ili

• GOTO obelezje - skok na deo programa u kome se nastavlja obrada, npr.izvestavanje o uzroku nastalog uslova.

Dakle, deklarativni iskaz WHENEVER omogucuje programeru da zada nacinna koji ce se proveravati vrednost promenljive SQLCODE nakon svake izvrseneSQL naredbe. Ovakvih naredbi moze biti veci broj u programu. Svaki WHENEVERiskaz odnosi se na sve SQL naredbe (u redosledu njihovog zapisa, a ne izvrse-nja) sve do navodenja sledeceg WHENEVER iskaza. Na primer, iskaz oblika:

EXEC SQL WHENEVER SQLERROR CONTINUE;

obezbedice nastavak izvrsavanja programa i u slucaju da je pri izvrsavanjuSQL naredbe doslo do greske. To znaci da program nece imati prinudni za-vrsetak, ali, sa druge strane, to obavezuje programera da posle svake SQLnaredbe u programu eksplicitno ispituje vrednost promenljive SQLCODE; uslucaju greske kontrolu upravljanja treba preneti na deo kojim se greska obra-duje. Ako ne postoji odgovarajuci WHENEVER iskaz, podrazumevana akcija jeCONTINUE.

Osim promenljive SQLCODE, SQLCA struktura ukljucuje i veci broj dru-gih promenljivih. Najvaznija medu njima je promenljiva SQLSTATE koja jetipa char[5] i slicno promenljivoj SQLCODE sadrzi kod rezultata izvrsavanjaSQL naredbe (npr. prva dva karaktera ’01’ promenljive SQLSTATE predstavl-jaju grupu kodova za upozorenja i ukazuju, slicno SQLCODE > 0, da je doslodo pojave koja rezultuje upozorenjem).

Medu ostalim zanimljivijim promenljivim SQLCA strukture je skup pro-menljivih SQLWARN0 – SQLWARN9 koje su tipa char i sadrze informacijeo uzroku upozorenja. Na primer, znacenje nekih od ovih elemenata SQLCAstrukture je sledece:

• SQLWARN0 ima vrednost ’W’ ako bar jedna od preostalih SQLWARNipromenljivih sadrzi upozorenje (’W’); tako uslov SQLWARNING u direktiviWHENEVER predstavlja disjunkciju uslova:

(SQLCODE > 0 AND SQLCODE <> 100) OR SQLWARN0 = ’W’;

Page 11: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.1. APLIKATIVNI (UGRAÐENI) SQL 11

• SQLWARN1 sadrzi ’W’ ako je pri dodeli promenljivoj maticnog jezikaodesecena vrednost kolone koja je tipa niska karaktera (CHAR(m));

• SQLWARN2 sadrzi ’W’ ako je doslo do eliminacije NULL vrednosti priprimeni agregatne funkcije.

SQLCODE i SQLWARN0,...SQLWARN9 su makroi, koji ukazuju na odgo-varajuce delove SQLCA strukture, tj. na polja sqlcode i delove niza karakterasqlwarn. Na primer, naredna funkcija bi se mogla koristiti za proveru da li jedoslo do greske:

int is_error( char error_string[], struct sqlca *sqlca_pointer){

if (sqlca_pointer->sqlcode < 0) {

printf ("ERROR occured : %s.\n SQLCODE : %ld\n",

error_string, sqlca_pointer->sqlcode);

return 1;

}

return 0;

}

Njena upotreba bi se mogla olaksati uvodenjem narednog makroa:

#define CHECKERR(message) if( is_error(message,&sqlca)!=0) return 1;

Komentari u okviru SQL naredbi

U okviru SQL naredbi mogu se koristiti standardni komentari na maticnomjeziku, kao i SQL komentari, koji pocinju sa dve crtice −− i traju do krajareda, jedino sto njima ne sme biti prekinut par kljucnih reci EXEC SQL. Dakle,naredna naredba ne bi bila ispravna:

EXEC -- ovo nije dobar komentar

SQL create view Knjige_2016

as select * from Knjige

where god_izdavanja = 2016;

Povezivanje na bazu podataka

Da bi program radio sa podacima iz neke baze podataka, neophodno je da seprethodno poveze na tu bazu. Ukoliko se u sam program ne ugradi povezi-vanje na bazu podataka, moze doci do nepredvidivih posledica ukoliko seprogram pokrene u okviru neke druge sheme iste baze podataka. Stoga jepreporucljivo da se program poveze na bazu podataka pre pocetka obrade ida raskine vezu po zavrsetku obrade. Ovo se postize SQL naredbama CONNECTi CONNECT RESET.

Faze prevodenja

Program koji u sebi sadrzi ugradeni SQL prevodi se u nekoliko koraka. Preprevodenja neophodno je prvo izvrsiti pretprocesiranje ugradenog SQL-a. Kaosto smo vec pomenuli, kao rezultat faze pretprocesiranja dobicemo program

Page 12: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

12GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

koji u sebi ne sadrzi SQL makroe vec CLI pozive i tzv. veznu datoteku kojaje potrebna za ugradnju paketa u bazu. Paket cini program koji koristi bazupodataka i podaci o tome kako to cini. Da bi se program mogao izvrsavatipotrebno je ugraditi paket u bazu, pri cemu se vrsi optimizacija svih pristupabazi od strane programa. Moguce je ponavljati ugradnju paketa u cilju opti-mizacije pristupa bazi u skladu sa najnovijim statistickim podacima.

Pretprocesiranje se vrsi DB2 naredbom PREP:

DB2 PREP datoteka.sqc BINDFILE

Kao rezultat dobijaju se dve datoteke sa istim nazivom ali ekstenzijama .c

i .bnd. Nakon faze pretprocesiranja moguce je vrsiti ugradnju paketa u bazunaredbom BIND:

DB2 BIND datoteka.bnd

Nakon ovoga potrebno je jos prevesti dobijenu c datoteku, a zatim i izvrsitilinkovanje sa odgovarajucom bibliotekom db2 funkcija.

Sekcija za deklaraciju host promenljivih

Host promenljive se deklarisu tako sto se njihove deklaracije postavljaju izmedudve ugradene SQL naredbe:

EXEC SQL BEGIN DECLARE SECTION;

...

EXEC SQL END DECLARE SECTION;

Ova sekcija se naziva sekcijom za deklaraciju. Format deklaracije pro-menljive treba da odgovara formatu maticnog jezika. Ima smisla deklarisatipromenljive samo onih tipova sa kojima se moze raditi i u maticnom jeziku i uSQL-u, kao sto su recimo celi brojevi, niske karaktera i slicno. Host promenljivai atribut mogu imati isti naziv.

U narednoj tabeli dat je pregled osnovnih SQL tipova i odgovarajucih Ctipova.

SQL tip C tipSMALLINT shortINTEGER longDOUBLE double

CHAR charCHAR(n) char[n+1]

VARCHAR(n) char[n+1]DATE char[11]TIME char[9]

Na primer, ukoliko bismo hteli da u programu koristimo host promenljivekoje ce sadrzati naziv knjige i godinu izdavanja, njih bismo mogli da deklari-semo na sledeci nacin:

Page 13: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.1. APLIKATIVNI (UGRAÐENI) SQL 13

EXEC SQL BEGIN DECLARE SECTION;

long k_sifra;

char naziv[51];

short godina_izdavanja;

EXEC SQL END DECLARE SECTION;

Koriscenje host promenljivih

Host promenljiva se moze koristiti u SQL naredbama na mestima gde se mozenaci konstanta. Podsetimo se da host promenljivoj prethodi dvotacka kadase koristi u SQL naredbi. Ukoliko se pokazivacke promenljive koriste u SQLnaredbama tada se moraju upotrebljavati sa tacno onoliko simbola ’*’ sa kolikosu definisane.

U nastavku je prikazan fragment programa u kome se od korisnika za-hteva da unese podatke o sifri knjige, njenom nazivu i godini izdavanja, zatimse ti podaci ucitavaju i oni se dodaju u tabelu Knjiga.

EXEC SQL BEGIN DECLARE SECTION;

long uneta_sifra;

char naziv[51];

short god_izdavanja;

EXEC SQL END DECLARE SECTION;

/* ovde bi islo ispisavanje poruke korisniku da unese

sifru knjige, njen naziv i godinu izdavanja, a zatim

ucitavanje podataka koje je korisnik uneo */

EXEC SQL INSERT INTO Knjiga(k_sifra,naziv,god_izdavanja)

VALUES (:uneta_sifra,:naziv,:god_izdavanja);

Poslednje dve linije koda sadrze ugradenu SQL naredbu INSERT. Ovojnaredbi prethodi par kljucnih reci EXEC SQL da bi se naznacilo da je ovo ugra-dena SQL naredba. Vrednosti koje se unose u ovim linijama nisu eksplicitnekonstante, vec host promenljive cije tekuce vrednosti postaju komponente n-torke koja se dodaje u tabelu.

Svaka SQL naredba koja ne vraca rezultat (tj. koja nije upit) se moze ugra-diti u program na maticnom jeziku dodavanjem kljucnih reci EXEC SQL isprednaredbe. Primeri naredbi koje se ovako mogu ugraditi su INSERT, UPDATE,DELETE i tvrdenja kojim se prave, menjaju ili brisu elementi sheme kao sto sutabele ili pogledi.

Upiti tipa SELECT-FROM-WHERE se ne mogu direktno ugraditi u maticnijezik zbog razlike u modelu podataka. Upiti kao rezultat proizvode skup n-torki, dok nijedan od glavnih maticnih jezika ne podrzava direktno skupovnitip podataka. Stoga, ugradeni SQL mora da koristi jedan od dva mehanizmaza povezivanje rezultata upita sa programom u maticnom jeziku, a to su:

1. SELECT naredba koja vraca tacno jedan red: ovakav upit moze svoj rezul-tat da sacuva u host promenljivima, za svaku komponentu n-torke.

2. kursori: upiti koji proizvode vise od jedne n-torke u rezultatu se moguizvrsavati ako se deklarise kursor za taj upit; opseg kursora cine sve

Page 14: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

14GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

n-torke rezultujuce relacije i svaka n-torka se moze prihvatiti u hostpromenljivima i obradivati programom u maticnom jeziku.

Upiti koji vracaju tacno jedan red

Forma naredbe SELECT koja vraca tacno jedan red je ekvivalentna formi SELECT-FROM-WHERE naredbe, osim sto stavku SELECT prati kljucna rec INTO i listahost promenljivih. Ove host promenljive se pisu sa dvotackom ispred naziva,kao sto je slucaj i sa svim host promenljivim u okviru SQL naredbe. Akoje rezultat upita tacno jedna n-torka, onda komponente ove n-torke postajuvrednosti datih promenljivih. Ako je rezultat prazan skup ili vise od jednen-torke, onda se ne vrsi nikakva dodela host promenljivim i odgovarajuci kodza gresku se upisuje u promenljivu SQLSTATE.

EXEC SQL SELECT naziv, god_izdavanja

INTO :naziv, :godina_izdavanja

FROM Knjiga

WHERE k_sifra=:uneta_sifra;

S obzirom na to da je atribut k sifra primarni kljuc tabele Knjiga, rezultatprethodnog upita je najvise jedna n-torka, tj. tabela sa jednom vrstom cije sevrednosti atributa naziv i god izdavanja upisuju, redom, u host promenljivenaziv i godina izdavanja. Ovde je dat primer kada su isto imenovani atributtabele i odgovarajuca host promenljiva.

U slucaju da je u navedenom primeru vrednost atributa god izdavanja

bila NULL, doslo bi do greske pri izvrsenju SELECT naredbe, jer host pro-menljiva godina izdavanja ne moze da sacuva NULL vrednost. Iz ovog ra-zloga se uz host promenljive koje mogu imati nedefinisanu (NULL) vrednostuvode i indikatorske promenljive koje na neki nacin mogu da sacuvaju in-formaciju da li je vrednost odgovarajuceg atributa NULL. Stoga, obracanjehost promenljivoj bice sada oblika :promenljiva:ind promenljiva (nazivuindikatorske promenljive moze da prethodi kljucna rec INDICATOR). Indika-torske promenljive su tipa koji odgovara SQL tipu SMALLINT (u C-u je toshort).

U slucaju naredbe SELECT INTO, ako je vrednost atributa u SELECT linijiNULL, vrednost host promenljive nece se promeniti, a odgovarajuca indika-torska promenljiva dobice negativnu vrednost. Stoga bi prethodni kod biooblika:

EXEC SQL SELECT naziv, god_izdavanja

INTO :naziv, :godina_izdavanja:ind_godina_izdavanja

FROM Knjiga

WHERE k_sifra=:uneta_sifra;

Za promenljivu naziv nije potrebno uvoditi odgovarajucu indikatorskupromenljivu jer je atribut naziv definisan sa opcijom NOT NULL te ne mozeimati nedefinisanu vrednost.

Page 15: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.1. APLIKATIVNI (UGRAÐENI) SQL 15

Kursori

Najcesci nacin za povezivanje upita iz SQL-a sa maticnim jezikom jeste posred-stvom kursora koji prolazi redom kroz sve n-torke relacije. Ova relacija mozebiti neka od postojecih tabela ili moze biti dobijena kao rezultat upita. Kursoripredstavljaju jedan vid “pokazivaca” na jedan red rezultata upita i mogu sepostepeno pomerati unapred po rezultujucoj tabeli.

Da bismo napravili i koristili kursor, potrebni su nam naredni koraci:

1. deklaracija kursora, koja ima formu:

EXEC SQL DECLARE <naziv_kursora> CURSOR FOR <upit>;

Opseg kursora cine n-torke relacije dobijene upitom.

2. otvaranje kursora, koje ima formu:

EXEC SQL OPEN <naziv_kursora>;

Ovim se izvrsava upit kojim je kursor definisan i kursor se dovodi ustanje u kojem je spreman da prihvati prvu n-torku relacije nad kojom jedeklarisan.

3. jedna ili vise naredbi citanja podataka, kojom se dobija naredna n-torkarelacije nad kojom je kursor deklarisan. Ova naredba ima formu:

EXEC SQL FETCH <naziv_kursora> INTO <lista_promenljivih>;

U listi promenljivih mora da postoji po jedna promenljiva odgovarajucegtipa za svaki atribut relacije. Ako postoji n-torka relacije koja se mozeprocitati, navedene promenljive dobijaju vrednosti odgovarajucih kom-ponenti te n-torke. Ako vise nema n-torki u relaciji (iscrpeli smo celurelaciju), onda se ne vraca nijedna n-torka, vrednost promenljive SQL-CODE postaje 100, a vrednost promenljive SQLSTATE se postavlja na’02000’ sto znaci da nije pronadena nijedna n-torka.

4. zatvaranje kursora, koje ima formu:

EXEC SQL CLOSE <naziv_kursora>;

Kada se kursor zatvori, onda on vise nema vrednost neke n-torke relacijenad kojom je definisan. Ipak, on se moze opet otvoriti i onda ce opetuzimati vrednosti iz skupa n-torki relacije.

FETCH naredba je jedina naredba kojom se kursor moze pomerati. Posto, uopstem slucaju, rezultujuca tabela sadrzi veci broj vrsta, pretrazivanje vrste izrezultujuce tabele obicno se stavlja u petlju (WHILE, na primer, u C-u). Petljase ponavlja sve dok ima vrsta u rezultujucoj tabeli. Po izlasku iz petlje kursorse zatvara.

Jedan program moze imati veci broj deklaracija (razlicitih) kursora.U nastavku je dat fragment koda kojim se koriscenjem kursora ispisuju red

po red informacije o sifri, nazivu i izdavacu svih knjiga izdatih u 2016. godini.

Page 16: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

16GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

...

/* funkcija za obradu greske */

int iserror(char err[]){

if (SQLCODE < 0){

printf("SQLCODE %ld %s\n\n", SQLCODE, err);

return 1;

}

return 0;

}

/* za poziv funkcije greske koristice se makro */

#define CHECKERR(s) if (iserror(s)) exit(1);

....

/* deklaracija kursora */

EXEC SQL DECLARE kursor_o_knjigama CURSOR FOR

select k_sifra, naziv, izdavac

from Knjiga

where god_izdavanja = 2016;

CHECKERR("Declare kursor_o_knjigama");

/* otvaranje kursora */

EXEC SQL OPEN kursor_o_knjigama;

CHECKERR("Open kursor_o_knjigama");

/* sve dok ima jos vrsta i FETCH se uspesno izvrsava */

WHILE (1){

/* cita se sledeca vrsta */

EXEC SQL FETCH kursor_o_knjigama

INTO :k_sifra, :naziv, :izdavac:ind_izdavac;

CHECKERR("Fetch kursor_o_knjigama");

/* ako smo obradili poslednju n-torku relacije

izlazimo iz while petlje */

if (SQLCODE==100)

break;

/* obrada te vrste */

printf("Sifra: %ld, naziv knjige: %s ", k_sifra, naziv);

if (ind_izdavac<0)

printf("izdavac: nepoznat\n");

else

printf("izdavac: %s\n", izdavac);

}

EXEC SQL CLOSE kursor_o_knjigama;

Page 17: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.1. APLIKATIVNI (UGRAÐENI) SQL 17

CHECKERR("Close kursor_o_knjigama");

...

Deklarisanje kursora samo za citanje

Kursor moze biti deklarisan samo za citanje, za citanje i brisanje, ili za citanje,brisanje i menjanje podataka. U nekim slucajevima nije ocigledno da li je kur-sor deklarisan samo za citanje ili je njim dopusteno i brisanje, te je pozeljnoeksplicitno zadati tip kursora.

Postoje odredene situacije kada je zgodno deklarisati kursor samo za citanje.Ako kursor deklarisemo sa opcijom FOR READ ONLY (FOR FETCH ONLY) (ovaopcija se navodi na kraju deklaracije kursora), onda SUBP moze biti siguranda relacija nad kojom je deklarisan nece biti izmenjena iako joj dati kursorpristupa. Na ovaj nacin se omogucava racionalniji pristup podacima vecembroju korisnika jer SUBP zna da ce podaci biti samo citani od strane kursora ida se ne zahteva ekskluzivni pristup podacima.

Na primer, prethodno definisani kursor kursor o knjigama nam je sluziosamo za citanje, te smo ga mogli deklarisati i na sledeci nacin:

EXEC SQL DECLARE kursor_o_knjigama CURSOR FOR

select k_sifra, naziv, izdavac

from Knjiga

where god_izdavanja = 2016

FOR READ ONLY;

Izmene posredstvom kursora

Kada domen kursora cine n-torke neke bazne tabele (relacije koja se cuva ubazi podataka), onda se posredstvom kursora mogu ne samo citati vrednostitekuce n-torke, vec se ona moze i obrisati ili joj se moze izmeniti vrednost.Sintaksa naredbi UPDATE i DELETE jednaka je standardnoj sintaksi ovih naredbi,sa izuzetkom WHERE stavke koja ovde ima oblik:

WHERE CURRENT OF <naziv_kursora>

Naravno moguce je u programu na maticnom jeziku za datu n-torku ispitatisve zeljene uslove pre nego sto odlucimo da je obrisemo ili izmenimo. Pritom,ako zelimo da podatke menjamo preko kursora, potrebno je u deklaraciji kur-sora nakon upita navesti stavku:

FOR UPDATE OF <lista_atributa>

gde <lista atributa> oznacava imena atributa, medusobno razdvojenih zare-zom, koje je dozvoljeno menjati koriscenjem kursora.

Upotrebom kursora moze se jednom naredbom izmeniti, odnosno obrisatisamo jedan red i to onaj koji je poslednji procitan. Neposredno nakon brisanjaposlednjeg procitanog reda, kursor se moze upotrebljavati samo za citanjenarednog reda.

Na primer, mogli bismo definisati kursor kojim je moguce izmeniti naziveknjiga ciji je izdavac Prosveta. Da li ce naziv biti izmenjen, zavisi od interakcijesa korisnikom.

Page 18: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

18GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

/* deklaracija kursora */

EXEC SQL DECLARE promeni_naziv CURSOR FOR

SELECT k_sifra, naziv

FROM Knjiga

WHERE izdavac = ’Prosveta’

FOR UPDATE OF naziv;

/* otvaranje kursora */

EXEC SQL OPEN promeni_naziv;

/* sve dok ima jos vrsta i FETCH se uspesno izvrsava */

WHILE (1){

/* cita se sledeca vrsta */

EXEC SQL FETCH promeni_naziv INTO :k_sifra, :naziv;

/* ako je doslo do neke greske ili smo obradili poslednju

n-torku relacije, izlazimo iz while petlje */

if (SQLCODE!=0)

break;

/* interakcija sa korisnikom */

printf("Da li zelite da izmenite naziv knjige sa sifrom %ld

ciji je naziv %s? Uneti d ili n.\n", k_sifra, naziv);

c = getchar();

/* jos jedan getchar() da procitamo i znak za novi red */

getchar();

if (c == ’d’ || c == ’D’){

/* obrada te vrste */

printf("Uneti novi naziv knjige\n");

scanf("%s",novi_naziv);

EXEC SQL UPDATE Knjiga

SET naziv = :novi_naziv

WHERE CURRENT OF promeni_naziv;

}

}

EXEC SQL CLOSE promeni_naziv;

Kursor se implicitno ogranicava samo za citanje ako SELECT naredba ukljucujeneku od sledecih konstrukcija:

• DISTINCT opciju u spoljasnjoj SELECT liniji;

• skupovnu (UNION, INTERSECT, EXCEPT) operaciju osim UNION ALL;

• agregatnu funkciju u spoljasnjoj SELECT liniji;

• GROUP BY ili HAVING stavku u spoljasnjoj SELECT naredbi;

Page 19: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.2. DINAMICKI SQL 19

• ORDER BY stavku;

• podupit nad istom tabelom;

• dve ili vise tabela u FROM liniji;

• tabelu ili pogled (u FROM liniji) koji se ne mogu azurirati.

2.2 Dinamicki SQL

Kao sto smo vec napomenuli, svaka ugnjezdena staticka SQL naredba je ufazi pretprocesiranja sasvim precizno odredena u smislu da je poznat njen tip(zna se da je u pitanju recimo naredba SELECT ili naredba UPDATE ili naredbaINSERT) i da su poznata imena tabela i kolona koje u njoj ucestvuju. SQLnaredba se zamenjuje pozivom (u maticnom jeziku) odgovarajuce CLI proce-dure, ali se izvrsavanjem programa taj poziv (pa dakle i sama SQL naredba)ne menja.

Za razliku od ovog pristupa, u dinamickom SQL-u naredbe nisu poznateu vreme pisanja programa i preciziraju se tek u fazi izvrsavanja programa.Takve SQL naredbe, umesto da se eksplicitno navode u programu, zadaju seu obliku niske karaktera koja se dodeljuje host promenljivoj. SQL naredba setada izgraduje na osnovu podataka iz programa (npr. vrednost odgovarajucehost promenljive moze se uneti sa standardnog ulaza). Dinamicki programinude vecu slobodu prilikom pisanja jer se delovi naredbe, cak i kompletnenaredbe mogu formirati na osnovu informacija koje dostavlja korisnik. Medu-tim, ovako pisani programi se moraju svaki put prilikom izvrsavanja iznovaanalizirati i optimizovati od strane sistema DB2.

Kako vrednost host promenljive moze da se menja u toku izvrsavanja pro-grama, to i SQL naredba dodeljena toj host promenljivoj takode moze da semenja u toku izvrsavanja programa.

Da bi dinamicka SQL naredba mogla da se izvrsi, potrebno je pripremiti jeza izvrsenje ugnjezdenom (statickom) naredbom PREPARE. Nakon toga se di-namicka naredba moze izvrsiti ugnjezdenom (statickom) naredbom EXECUTE.

Tipovi dinamickih naredbi

U zavisnosti od tipa naredbe koja se dinamicki izvrsava zavisi i odgovarajucikod. Naredba SELECT se mora razmatrati na drugaciji nacin jer ona vraca po-datke i program mora biti spreman da primi te podatke. S obzirom na to dakolone koje se izdvajaju mogu biti nepoznate u vreme pisanja programa, pros-tor za smestanje podataka se mora alocirati u vreme izvrsavanja. Za naredbekoje nisu tipa SELECT ovo nije neophodno.

Pored toga, parametrizovana tvrdenja zahtevaju slozenije tehnike kodi-ranja od gotovih tvrdenja jer se parametrima mora dodeliti vrednost pre izvr-savanja naredbe.

Postoje, naravno, i situacije u kojima jednostavno ne znamo unapred kojice se tip naredbe izvrsavati (na primer, korisnik sa standardnog ulaza unosiproizvoljnu naredbu koju treba dinamicki izvrsiti).

Dakle, razlikujemo sledece tipove naredbi:

• naredba koje nija SELECT

Page 20: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

20GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

– potpuna– parametrizovana

• SELECT naredba

– sa fiksnom listom kolona koje se izdvajaju– sa promenljivom listom kolona koje se izdvajaju

• nepoznata naredba

Naredba PREPARE

Naredba PREPARE prevodi tekstualnu formu SQL naredbe u izvrsni oblik, do-deljuje pripremljenoj naredbi naziv i eventualno upisuje potrebne informacijeu SQLDA strukturu. Njena sintaksa je:

PREPARE <naziv_naredbe> [INTO <ime_deskriptora>]

FROM <host_prom>

gde je <naziv naredbe> ime koje se koristi za identifikovanje pripremljenenaredbe, a <host prom> niska karaktera koja sadrzi tekst naredbe. Ako se uokviru naredbe koristi i stavka INTO onda se navedeni deskriptor popunjavainformacijama kao u slucaju naredbe DESCRIBE (o kojoj ce biti reci malo kas-nije). U okviru naredbe koja se priprema ne sme se pojavljivati niz kljucnihreci EXEC SQL, znak za kraj naredbe ’;’, host promenljive, niti komentari.

Neka je npr. V1 host promenljiva koja je u programu dobila vrednost –nisku karaktera neke izvrsne SQL naredbe. Tada naredba:

EXEC SQL PREPARE S1 FROM :V1;

na osnovu niske karaktera iz host promenljive V1 kreira izvrsnu SQL naredbucije je ime S1. Posle provere uspesnosti izvrsenja PREPARE naredbe pripreml-jena naredba se moze veci broj puta izvrsiti koriscenjem naredbe EXECUTE.

Kao sto je vec receno, dinamicka SQL naredba ne sme da sadrzi obracanjahost promenljivim. Umesto toga mogu se koristiti oznake parametara. Oz-naka parametra je znak pitanja ’?’ i navodi se na mestu na kome bi se navelahost promenljiva kada bi naredba bila staticka. Postoje dve vrste oznakaparametara: sa opisom tipa i bez opisa tipa. Oznake parametara bez tipa seoznacavaju samo znakom pitanja, a sa tipom kao: CAST (? AS <tip>). Oz-nake parametara bez opisa tipa mogu se koristiti na mestima gde se u fazipripreme moze na nedvosmislen nacin na osnovu konteksta odrediti njihovtip.

Na primer, ispravna dinamicka SQL naredba bi mogla imati oblik

INSERT INTO Knjiga VALUES (?, ?, ?, ?)

jer se iz same naredbe mogu odrediti tipovi parametara, dok je u narednomslucaju neophodno eksplicitno zadati tip parametra:

SELECT CAST(? AS INTEGER) FROM Knjiga

U vreme izvrsavanja pripremljene SQL naredbe, oznake parametara se za-menjuju tekucim vrednostima host promenljivih (ili strukture) koje se navodeu EXECUTE naredbi.

Page 21: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.2. DINAMICKI SQL 21

Naredba EXECUTE

Naredba EXECUTE se moze upotrebljavati u dva oblika:

EXECUTE <naziv_naredbe> [USING <lista_host_prom>]

ili:

EXECUTE <naziv_naredbe> [USING DESCRIPTOR <ime_deskriptora>]

Ako pripremljena naredba sadrzi oznake parametara, u okviru EXECUTE

naredbe mora se koristiti neka od USING stavki. U slucaju da se navodi listahost promenljivih, njihov broj mora odgovarati broju oznaka parametara uokviru naredbe, a tipovi host promenljivih redom tipovima parametara.

Na primer, ako je vrednost host promenljive V1 niska karaktera “INSERTINTO Knjiga VALUES (?, ?, ?, ?)”, posle izvrsavanja naredbe:

EXEC SQL PREPARE k_insert FROM :V1;

moze se izvrsiti naredba:

EXEC SQL EXECUTE k_insert

USING :k_sifra, :k_naziv, :k_izdavac, :k_god;

pri cemu su k sifra, k naziv, k izdavac i k god host promenljive koje odgo-varaju shemi tabele Knjiga.

Ako se upotrebljava druga vrsta USING stavke, njen argument je SQLDAstruktura koja mora biti popunjena podacima o parametrima na odgovarajucinacin. Sledeca polja strukture se moraju popuniti:

• polje SQLN sadrzi broj alociranih SQLVAR struktura,

• polje SQLDABC sadrzi ukupan broj bajtova alociranih za SQLDA struk-turu,

• polje SQLD sadrzi broj promenljivih koji se upotrebljava pri obradi na-redbe,

• polje SQLVAR sadrzi opise pojedinacnih promenljivih.

Ako se za izvrsavanje naredbe koristi ovaj pristup, potrebno je alociratidovoljno veliku SQLDA strukturu koja moze da primi sve potrebne podatke.Za izracunavanje broja bajtova koji je potreban za smestanje svih podatakakoristi se makro SQLDASIZE(n), gde je n broj potrebnih SQLVAR struktura.

Pre nego sto pocne izvrsavanje naredbe svaka oznaka parametra zamen-juje se odgovarajucom vrednoscu parametra.

Prethodnu naredbu mozemo izvrsiti koriscenjem SQLDA strukture na sledecinacin:

Page 22: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

22GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

...

strcpy (k_niska,"INSERT INTO Knjiga VALUES(?,?,?,?)");

EXEC SQL PREPARE k_insert FROM :k_niska;

...

/* priprema SQLDA strukture mojDA */

...

EXEC SQL EXECUTE k_insert USING DESCRIPTOR :mojDA;

...

Treba obratiti paznju da je identifikator deskriptorske strukture takodehost promenljiva, te se u SQL naredbama koristi sa dvotackom.

Dinamicki se mogu pripremiti i izvrsiti samo izvrsne SQL naredbe, i to nebas sve. Neke od naredbi koje se mogu izvrsiti (date u abecednom redosledu)su: ALTER, CREATE, DELETE, DROP, INSERT, SELECT, UPDATE. Medu izvrsnimSQL naredbama koje ne mogu da se izvrsavaju dinamicki nalaze se naredbe:CLOSE, DECLARE, EXECUTE, EXECUTE IMMEDIATE, FETCH, OPEN, PREPARE.

Naredba EXECUTE IMMEDIATE

Moguce je koristiti i ugnjezdenu (staticku) naredbu EXECUTE IMMEDIATE da bise u jednom koraku pripremila i izvrsila dinamicka SQL naredba. Sintaksaove naredbe je:

EXECUTE IMMEDIATE <host_prom>

gde je <host prom> host promenljiva koja sadrzi nisku karaktera sa tekstomnaredbe. U okviru naredbe se ne sme pojavljivati niz kljucnih reci EXEC SQL,znak za kraj naredbe ’;’, host promenljive, oznake parametara, niti komentari.

Na ovaj nacin se moze izvrsiti svaka naredba koja nije SELECT, ako nijeparametrizovana, tj. ako ne sadrzi oznake parametara.

Kod ove naredbe se cena pripreme naredbe placa svaki put kada se onaizvrsava, te se ova naredba obicno primenjuje kada je dinamicku SQL naredbupotrebno izvrsiti samo jednom.

Ako je, na primer, vrednost host promenljive V1 niska karaktera “DELETEFROM Knjiga WHERE k sifra = 101”, onda se naredbom:

EXEC SQL EXECUTE IMMEDIATE :V1;

izvrsava naredba DELETE nad tabelom Knjiga, cime se brise knjiga sa sifrom101, ako takva postoji.

Naredba DESCRIBE

Naredba DESCRIBE upisuje potrebne informacije o naredbi u SQLDA struk-turu, pod pretpostavkom da je vec izvrsena njena priprema. Da bi se SQLDAstruktura mogla upotrebljavati neophodno je ukljuciti odgovarajuce zaglavljenaredbom:

EXEC SQL INCLUDE SQLDA;

Naredba DESCRIBE se upotrebljava u formi:

Page 23: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.2. DINAMICKI SQL 23

DESCRIBE <naziv_naredbe> INTO <ime_deskriptora>

pri cemu mora postojati dinamicka SQL naredba pripremljena pod datim nazivomi mora biti alocirana odgovarajuca SQLDA deskriptorska struktura. Bitno jeda je unapred popunjeno polje SQLN strukture SQLDA, koje sadrzi maksi-malan broj promenljivih cije je opise SQLDA struktura u stanju da sadrzi, amoze biti i nula.

Nakon izvrsavanja naredbe DESCRIBE SQLDA struktura se popunjava nasledeci nacin:

• polje SQLDABC sadrzi velicinu strukture u bajtovima;

• polje SQLD sadrzi broj kolona u rezultujucoj tabeli ako je u pitanju naredbaSELECT, a 0 inace;

• polje SQLVAR sadrzi podatke o pojedinacnim parametrima: ako je SQLDnula, ili je vece od SQLN, ne dodeljuje se nista SQLVAR elementima.

Svaka SQLVAR struktura ima sledece elemente:

• polje SQLTYPE sadrzi oznaku tipa parametra i oznaku da li moze sadrzatiNULL vrednost;

• polje SQLLEN sadrzi velicinu parametra u bajtovima;

• polje SQLNAME sadrzi naziv kolone ili tekstom zapisan broj koji opisujeoriginalnu poziciju izvedene kolone

Oznake tipova se dobijaju tako sto se na nisku SQL TYP nadoveze nazivodgovarajuceg SQL tipa, na primer SQL TYP SMALLINT. Ukoliko parametarmoze imati NULL vrednost, dodaje se slovo N pre imena tipa, recimo u pret-hodnom slucaju SQL TYP NSMALLINT

Korisnik je duzan da nakon izvrsavanja naredbe DESCRIBE odgovarajucimpodacima popuni preostala polja SQLVAR strukture:

• polje SQLDATA mora sadrzati pokazivac na prostor predviden za param-etar (bilo za citanje ili pisanje parametra);

• polje SQLIND mora sadrzati pokazivac na prostor predviden za indika-tor, ako parametar moze imati NULL vrednost.

Alociranje SQLDA strukture moze se vrsiti na dva nacina: alokacijom sadovoljno mesta (postavljanjem polja SQLN na dovoljno veliku vrednost) ili udva koraka: prvi korak bila bi alokacija SQLDA strukture bez ijednog SQL-VAR elementa i izvrsavanje naredbe DESCRIBE u cilju dobijanja pravih infor-macija (polje SQLD sadrzace broj kolona u rezultatu), a drugi korak da se nakontoga ponovljenom alokacijom (postavljanjem polja SQLN na vrednost vecu ilijednaku od vrednosti polja SQLD) obezbedi dovoljno prostora.

Na primer, SQLDA strukturu mozemo formirati i popuniti jednom pro-menljivom u pokretnom zarezu koja je pracena indikatorom na sledeci nacin:

Page 24: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

24GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

...

struct sqlda *mojDA = (struct sqlda*)malloc(SQLDASIZE(1));

double prom;

short prom_ind;

mojDA->sqln = mojDA->sqld = 1;

mojDA->sqlvar[0].sqltype = SQL_TYP_NFLOAT;

mojDA->sqlvar[0].sqllen = sizeof(double);

mojDA->sqlvar[0].sqldata = &prom;

mojDA->sqlvar[0].sqlind = &prom_ind;

...

Dinamicki kursori

Dinamicki pripremljena SELECT naredba se moze izvrsiti koriscenjem kur-sora. Samo rukovanje dinamickim kursorom je gotovo identicno rukovanjustatickim kursorom, jedina razlika je u tome sto se umesto statickog upitanavede ime pripremljenog dinamickog upita.

Dakle, prilikom rada sa dinamickim kursorima potrebno je da se izvrsenaredni koraci:

• priprema naredbe,

• deklarisanje kursora nad imenom naredbe,

• otvaranje kursora,

• uzimanje vrsta iz rezultujuce tabele,

• zatvaranje kursora.

Deklaracija dinamickog kursora izvodi se naredbom:

DECLARE <ime_kursora> CURSOR FOR <naziv_naredbe>

Kako se u dinamickim upitima mogu upotrebljavati oznake parametara,pri otvaranju kursora potrebno je navesti odgovarajuce vrednosti. To se postizena isti nacin kao i kod EXECUTE naredbe, u jednoj od dve forme:

OPEN <ime_kursora> [USING <lista_host_prom>]

OPEN <ime_kursora> [USING DECSRIPTOR <ime_deskriptora>]

Primetimo da se pri otvaranju kursora navedeni parametri samo citaju radiformiranja upita.

Pri citanju redova pomocu kursora moze se koristiti uobicajena forma:

FETCH <ime_kursora> INTO <lista_host_prom>

ili se moze upotrebljavati i deskriptor upita:

FETCH <ime_kursora> USING DECSRIPTOR <ime_deskriptora>

Page 25: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.2. DINAMICKI SQL 25

Primetimo da se pri citanju redova kursora navedeni parametri koristesamo za upisivanje vrednosti koje predstavljaju rezultat upita.

Pogledajmo na primeru dinamickog kursora kako se mogu ispisati oneknjige koje su izdate u godini koja se unosi sa standardnog ulaza.

...

/* deklaracija host promenljivih */

EXEC SQL BEGIN DECLARE SECTION;

long sifra; /* sifra knjige */

char naziv[51]; /* naziv knjige */

char izdavac[31]; /* izdavac */

short ind_izdavac; /* indikatorska promenljiva za izdavaca */

short godina; /* godina izdavanja */

char naredba[255]; /* promenljiva u kojoj ce biti naredba */

EXEC SQL END DECLARE SECTION;

...

/* definisanje komande sa parametrom */

sprintf(naredba, "%s", "SELECT k_sifra, naziv, izdavac

FROM Knjiga WHERE god_izdavanja = ?");

/* prevodjenje komande iz tekstualnog u izvrsni oblik i

njeno imenovanje */

EXEC SQL PREPARE select_k FROM :naredba;

/* definisanje kursora */

EXEC SQL DECLARE c1 CURSOR FOR select_k;

printf("Unesite godinu izdavanja: ");

scanf("%hd",&godina);

/* otvaranje kursora i navodjenje vrednosti parametra */

EXEC SQL OPEN c1 USING :godina;

/* sve dok ima redova u rezultatu ... */

while(1){

/* cita se red po red */

EXEC SQL FETCH c1 INTO :sifra, :naziv, :izdavac:ind_izdavac;

/* ako su procitani svi redovi izlazi se iz petlje */

if (SQLCODE==100) break;

/* inace, stampa se red rezultata */

printf("Sifra: %ld Naziv: %s \n", sifra, naziv);

if (ind_izdavac<0)

printf("Izdavac: nepoznat\n");

else

printf("Izdavac: %s\n", izdavac);

Page 26: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

26GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

}

/* zatvara se kursor */

EXEC SQL CLOSE c1;

...

Dakle, ukoliko je u vreme pripreme programa poznat broj kolona kojimace se pristupati i njihovi tipovi, rad sa parametrizovanom SELECT naredbomnije nimalo komplikovaniji od rada sa statickom naredbom. Ukoliko se uvreme pisanja programa ne zna kojim kolonama ce se pristupati, ne mozese unapred alocirati prostor za smestanje host promenljivih, vec se to moraraditi u vreme izvrsavanja, koriscenjem SQLDA strukture.

2.3 Direktni pozivi funkcija SUBP (CLI)

DB2 CLI je IBM-ov C i C++ aplikacioni programski interfejs za pristup rela-cionim bazama podataka koji koristi pozive funkcija za prosledivanje dina-mickih SQL naredbi kao argumenata funkcija.

Program koji koristi ugradeni SQL je potrebno pretprocesirati da bi se SQLnaredbe transformisale u kod, koji se zatim kompajlira, vezuje sa bazu po-dataka i izvrsava. DB2 CLI program ne zahteva pretprocesiranje niti vezi-vanje za bazu podataka, vec koristi standardni skup funkcija za izvrsavanjeSQL naredbi i odgovarajucih servisa u vreme izvrsavanja.

Ova razlika je znacajna jer su pretprocesori, tradicionalno, specificni zaneki konkretan proizvod koji radi nad bazom, sto efektivno vezuje razvijenuaplikaciju za taj proizvod. DB2 CLI omogucava pisanje portabilnih aplikacijakoje su nezavisne od konkretnog proizvoda baza podataka. Ova nezavisnostznaci da DB2 CLI aplikaciju nema potrebe ponovo pretprocesirati ili iznovavezivati da bi se pristupilo drugom proizvodu baza podataka. One se samopovezuju sa odgovarajucom bazom podataka u vreme izvrsavanja programa.

DB2 CLI takode eliminise potrebu za globalnim oblastima za podatke kojekontrolisu aplikacije, kao sto su SQLCA i SQLDA, koje se koriste u ugradenomSQL-u. Umesto toga, DB2 CLI sam alocira i kontrolise potrebne strukture po-dataka i obezbeduje mehanizme kojima aplikacija moze na njih da referise.

Slogovi

Program u programskom jeziku C koji koristi CLI mora da ukljuci zaglavljesqlcli.h u kome su deklarisane funkcije, tipovi podataka, strukture, kao isimbolicke konstante potrebne za rad u ovom pristupu.

U programu se mogu kreirati i moze se raditi sa cetiri tipa slogova (struk-tura u C-u):

• okruzenjima – slog ovog tipa se pravi od strane aplikacije kao pripremaza jednu ili vise konekcija sa bazom podataka;

• konekcijama – slog ovog tipa se pravi da bi se aplikacija povezala sabazom podataka; svaka konekcija postoji unutar nekog okruzenja; ap-likacija moze biti povezana sa vise razlicitih baza podataka u isto vreme,a moze uspostaviti i vise razlicitih konekcija sa istom bazom podataka.

Page 27: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.3. DIREKTNI POZIVI FUNKCIJA SUBP (CLI) 27

• naredbama – u programu se moze napraviti jedan ili vise slogova naredbi.Svaki od njih cuva informaciju o pojedinacnoj SQL naredbi, koja ukljucujei podrazumevani kursor ako je naredba upit. U razlicito vreme ista CLInaredba moze da predstavlja razlicite SQL naredbe;

• opisima – slogovi ovog tipa cuvaju informacije o kolonama u skupu rezul-tata upita ili o dinamickim parametrima u SQL naredbama. Svaka naredbaima nekoliko opisnih slogova koji se implicitno prave (nazivi atributa injihovi tipovi), a korisnik ih moze napraviti jos, ukoliko je potrebno.

Navedenim slogovima se u programu rukuje tako sto se prosleduje po-kazivac na slog (eng. handle). U narednom tekstu necemo praviti razlikuizmedu sloga i pokazivaca na njega.

U zaglavlju sqlcli.h su definisani tipovi pokazivaca na okruzenja, konek-cije, naredbe i opise: SQLHENV, SQLHDBC, SQLHSTMT i SQLHDESC, redom.

Slogovi se prave koriscenjem funkcije:

SQLAllocHandle(hType, hIn, hOut)

Argumenti ove funkcije su:

1. hType je tip zeljenog sloga i ima vrednost SQL HANDLE ENV za novo o-kruzenje, SQL HANDLE DBC za novu konekciju, SQL HANDLE STMT za novunaredbu i SQL HANDLE DESC za novi opis.

2. hIn je slog elementa viseg nivoa u koji se novoalocirani element smesta.Ako pravimo slog okruzenja ovaj parametar ima vrednost SQL NULL HANDLE;time se funkciji SQLAllocHandle govori da za ovaj parametar ne pos-toji relevantna vrednost. Ako pravimo slog konekcije, onda je hIn slogokruzenja u okviru koga ce konekcija postojati, a ako pravimo slog naredbe,onda je hIn slog konekcije u okviru koje ce postojati naredba.

3. hOut je adresa sloga koji se kreira funkcijom SQLAllocHandle.

SQLAllocHandle vraca vrednost tipa SQLRETURN (celobrojnu vrednost). Ovavrednost je jednaka SQL SUCCESS ako je izvrsavanje naredbe proslo uspesno,bez greske.

#include "sqlcli.h"

SQLHENV mojeOkr;

SQLHDBC mojaKon;

SQLHSTMT naredba;

SQLRETURN kodGreske1, kodGreske2, kodGreske3;

kodGreske1 = SQLAllocHandle(SQL_HANDLE_ENV,

SQL_NULL_HANDLE, &mojeOkr);

if(kodGreske1 == SQL_SUCCESS) {

kodGreske2 = SQLAllocHandle(SQL_HANDLE_DBC,

mojeOkr, &mojaKon);

if(kodGreske2 == SQL_SUCCESS)

kodGreske3 = SQLAllocHandle(SQL_HANDLE_STMT,

mojaKon, &naredba);

}

Page 28: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

28GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

U prethodnom kodu deklarisani su slogovi okruzenja, konekcije i naredbe,redom. Nakon toga se poziva funkcija SQLAllocHandle kojom se zahtevaslog okruzenja (kao drugi argument prosleduje se NULL slog) a dobijeni slogsmesta se na adresu koja je prosledena kao treci argument ove funkcije. Akoje ova funkcija zavrsila sa uspehom, u okviru ovog okruzenja se pravi slogkonekcije, a zatim se (ako je uspesno dobijena konekcija) kreira u okviru ovekonekcije slog naredbe. Tipican redosled koraka prikazan je na slici 2.1.

Slika 2.1: Faza inicijalizacije i zavrsetka

Nakon sto slogovi vise nisu potrebni, treba ih osloboditi da bi se oslo-bodili. To se radi pozivom funkcije SQLFreeHandle(). Kao argument ovefunkcije potrebno je navesti alocirani slog. Pre oslobadanja sloga okruzenjapotrebno je osloboditi sve slogove konekcija za to okruzenje, inace ce bitijavljena greska i vracena vrednost SQL_ERROR. Pre oslobadanja sloga konek-cije potrebno je raskinuti vezu sa svim konekcijama koje postoje u tom slogukonekcije. Pozivom ove funkcije moguce je osloboditi i slog naredbe cime seoslobadaju svi resursi koji su zauzeti pozivom alokacije naredbe. Moguce jetakode osloboditi i slog opisa.

Page 29: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.3. DIREKTNI POZIVI FUNKCIJA SUBP (CLI) 29

Povezivanje na bazu podataka

U okviru koda potrebno je povezati se na bazu podataka i to se postize nared-bom:

SQLConnect(hdbc,db_name,db_name_len,user_name,user_name_len,

password,password_len);

pri cemu su argumenti ove funkcije redom:

1. hdbc – slog konekcije; funkcija SQLAllocHandle(SQL HANDLE DBC,...,&hdbc)

mora biti pozvana pre ove funkcije

2. db name – ime baze podataka

3. db name len – duzina imena baze podataka

4. user name – identifikator korisnika

5. user name len – duzina identifikatora korisnika

6. password – sifra

7. password len – duzina sifre

Moguce je za duzinu niske proslediti vrednost SQL NTS ukoliko je niskaterminisana (onda je za odredivanje njene duzine dovoljno da se niska skeniradok se ne naide na znak ’\0’). Ukoliko se na mestu identifikatora korisnika ilisifre (ili na oba ova mesta) prosledi vrednost NULL, konekcija se startuje uime korisnika koji pokrece CLI program.

Naredbom:

SQLDisconnect(hdbc);

prekida se konekcija sa bazom, pri cemu je hdbc slog konekcije.

Obrada naredbi

Proces pridruzivanja i izvrsavanja SQL naredbe je analogan pristupu koji sekoristi u dinamickom SQL-u: tamo smo pridruzivali tekst SQL naredbe odgo-varajucoj SQL promenljivoj koriscenjem naredbe PREPARE i onda je izvrsavalikoriscenjem naredbe EXECUTE. Ako na slog naredbe gledamo kao na SQL pro-menljivu, situacija sa CLI pristupom jeste prilicno slicna. Postoji funkcija:

SQLPrepare(sh, st, si)

ciji su argumenti:

1. sh – slog naredbe

2. st – niska karaktera koji sadrzi SQL naredbu

3. si – duzina niske karaktera st. Ukoliko duzina niske nije poznata, aniska je terminisana, moze se proslediti konstanta SQL NTS koja govorifunkciji SQLPrepare da sama izracuna duzinu niske na osnovu njenevrednosti.

Page 30: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

30GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

Efekat ove funkcije je da naredbu na koju referise slog sh poveze sa konkret-nom naredbom st.

Funkcijom:

SQLExecute(sh)

izvrsava se naredba na koju referise slog naredbe sh. Za mnoge forme SQLnaredbi, kao sto su umetanja i brisanja, efekat izvrsavanja naredbe je ocigledan.Manje ocigledno jeste sta je efekat ove naredbe ako je SQL naredba na koju sereferise upit. Kao sto cemo videti u nastavku postoji implicitni kursor koji jedeo samog sloga naredbe. Naredba se izvrsava tako sto se sve n-torke u rezul-tatu upita negde smestaju i cekaju da im se pristupi. Koriscenjem implicitnogkursora mozemo citati jednu po jednu n-torku, na nacin slican onome kakosmo radili sa standardnim kursorima.

Na primer, slogu naredba iz prethodnog primera moze se pridruziti naredba“SELECT god izdavanja FROM Knjiga”, a zatim se ona moze izvrsiti na sledecinacin:

SQLPrepare(naredba, "SELECT god_izdavanja FROM Knjiga", SQL_NTS);

SQLExecute(naredba);

ili

char *tekst_naredbe = "SELECT god_izdavanja FROM Knjiga";

SQLPrepare(naredba, (SQLCHAR *)tekst_naredbe, strlen(tekst_naredbe));

SQLExecute(naredba);

Kao i u slucaju dinamickog SQL-a, korak pripreme i izvrsavanja se moguobjediniti u jedan korak koriscenjem funkcije SQLExecDirect. Primer kojikombinuje linije iz prethodnog primera bi bio:

SQLExecDirect(naredba,

"SELECT god_izdavanja FROM Knjiga", SQL_NTS);

Citanje podataka iz rezultata upita

Kursor se otvara kada se dinamicka SELECT naredba uspesno izvrsi pozivomnaredbe SQLExecute() ili SQLExecDirect().

Funkcija u CLI koja odgovara naredbi FETCH u ugradenom SQL jeste:

SQLFetch(sh)

gde je sh slog naredbe. Pretpostavka je da je naredba na koju referise slog sh

vec izvrsena; ukoliko nije citanje podataka ce izazvati gresku. SQLFetch kaoi sve CLI funkcije vraca vrednost tipa SQLRETURN koja daje indikator uspehaili greske. Povratna vrednost SQL NO DATA nam govori da nema vise n-torki urezultatu upita. Kao i u slucaju ugradenog SQL-a, ova vrednost ce se koristitida bismo izasli iz petlje u kojoj citamo nove n-torke.

Dakle, u slucaju naredbe SELECT poziv SQLExecute bice pracen sa jednimili vise poziva SQLFetch. Logicno pitanje je odakle dolaze n-torke? Kom-ponente n-torke smestaju se u jedan od opisnih slogova koji su pridruzeni

Page 31: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.3. DIREKTNI POZIVI FUNKCIJA SUBP (CLI) 31

naredbi ciji se slog javlja u pozivu funkcije SQLFetch. Komponenta se mozepovezati sa promenljivom u maticnom jeziku, pre nego sto pocnemo da citamopodatke, pozivom funkcije:

SQLBindCol(sh, colNo, colType, pVar, varSize, varInfo)

Znacenje argumenata ove funkcije je sledece:

1. sh je slog ukljucene naredbe,

2. colNo je redni broj komponente (u okviru n-torke) cije vrednosti citamo,

3. colType je kod tipa promenljive u koju se smesta vrednost komponente(kodovi su definisani u sqlcli.h i imaju vrednosti npr. SQL CHAR zaniske karaktera ili SQL INTEGER za cele brojeve),

4. pVar je pokazivac na promenljivu u koju se smesta vrednost,

5. varSize je velicina u bajtovima vrednosti promenljive na koju pokazujepVar,

6. varInfo je pokazivac na celobrojnu vrednost koja se moze koristiti dabi se obezbedile neke dodatne informacije; na primer poziv SQLFetch()

vraca vrednost SQL_NULL_DATA na ovom mestu argumenta, ako je vred-nost kolone NULL

Napisimo funkciju kojom bi se utvrdivalo da li je vise knjiga izdato u 2000.godini ili u 2010. godini. Da bi kod bio sto sazetiji preskacemo sve proveregreski, osim testiranja da li je funkcija SQLFetch vratila da nema vise n-torki.

#include "sqlcli.h"

void vise_knjiga(){

int br_2000=0, br_2010=0;

SQLHENV mojeOkr;

SQLHDBC mojaKon;

SQLHSTMT naredba;

SQLSMALLINT godina, godinaInfo;

SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, mojeOkr);

SQLAllocHandle(SQL_HANDLE_DBC, mojeOkr, &mojaKon);

SQLAllocHandle(SQL_HANDLE_STMT, mojaKon, &naredba);

SQLPrepare(naredba,"SELECT god_izdavanja FROM Knjiga", SQL_NTS);

SQLExecute(naredba);

SQLBindCol(naredba, 1, SQL_SMALLINT,

&godina, sizeof(godina), &godinaInfo);

while(SQLFetch(naredba) != SQL_NO_DATA) {

if (godina == 2000)

br_2000++;

else if (godina == 2010)

br_2010++;

}

Page 32: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

32GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

if (br_2000 > br_2010)

printf("Vise knjiga je izdato u 2000. godini\n");

else

printf("Vise knjiga je izdato u 2010. godini\n");

}

U ovom primeru deklarisali smo promenljivu godina koja odgovara hostpromenljivoj u ugradenom SQL-u i promenljivu godinaInfo koje je potrebnazbog poziva funkcije SQLBindCol ali se ne koristi.

Prosledivanje parametara upitu

Ugradeni SQL daje mogucnost da se izvrsi SQL naredba, pri cemu se deote naredbe sastoji od vrednosti koje su odredene tekucim vrednostima hostpromenljivih. Slican mehanizam postoji i u CLI pristupu, ali je malo komp-likovaniji. Koraci koji su potrebni su:

1. iskoristiti SQLPrepare za pripremu naredbe u kojoj su neki delovi kojenazivamo parametrima zamenjeni znakom pitanja. i-ti znak pitanja pred-stavlja i-ti parametar

2. iskoristiti funkciju SQLBindParameter za vezivanje vrednosti za mestana kojima se nalaze znakovi pitanja.

3. izvrsiti upit koriscenjem ovih veza, pozivom funkcije SQLExecute. Prime-timo da ako promenimo vrednost jednog ili vise parametara, moramoponovo da pozovemo ovu funkciju

Funkcija SQLBindParameter() ima 10 argumenata:

1. sh je slog ukljucene naredbe,

2. parNo je redni broj parametra (pocevsi od 1)

3. parType je tip parametra: SQL_PARAM_INPUT – za SQL naredbe koje nisuzapamcene procedure, SQL_PARAM_OUTPUT – izlazni parametar zapamceneprocedure, SQL_PARAM_INPUT_OUTPUT – ulazno-izlazni parametar zapam-cene procedure,

4. valueType je C tip parametra, npr. SQL_C_LONG,

5. parType je SQL tip parametra, npr. SQL_INTEGER,

6. colSize je preciznost odgovarajuceg parametra, npr. maksimalna duzinaniske

7. decimalDigits je broj decimala, ako je tip parametra SQL_DECIMAL

8. parValPtr je bafer za smestanje parametra

9. bufferLen je velicina bafera za smestanje parametra

10. indPtr je pokazivac na lokaciju koja sadrzi duzinu parametra koja secuva u parValPtr; sluzi npr. za zadavanje NULL vrednosti parametratako sto se vrednost ovog polja postavi na vrednost SQL_NULL_DATA

Page 33: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.4. UPOTREBA ODBC STANDARDA 33

Naredni primer ilustruje ovaj proces i ukazuje na najznacajnije argumentefunkcije SQLBindParameter.

Ideja je da se vrednosti sifre knjige i njenog naziva unose sa standardnogulaza i da se onda unete vrednosti koriste kao deo n-torke koju dodajemo utabelu Knjiga.

...

/* ucitavamo vrednosti promenljivih sifra_knjige i naziv_knjige */

scanf("%ld",&sifra_knjige);

scanf("%s",naziv_knjige);

SQLPrepare(mojaNaredba,

"INSERT INTO Knjiga(k_sifra, naziv) VALUES (?, ?)", SQL_NTS);

SQLBindParameter(mojaNaredba, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,

0, 0, &sifra_knjige, 0, 0, NULL);

SQLBindParameter(mojaNaredba, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,

50, 0, naziv_knjige, 50, 0, NULL);

SQLExecute(mojaNaredba);

...

2.4 Upotreba ODBC standarda

Kao sto smo vec napomenuli, cilj razvoja CLI interfejsa bio je da se povecaportabilnost aplikacija tako sto im se omogucava da postanu nezavisne odkonkretnog korisnickog programskog interfejsa. Microsoft je razvio SQL in-terfejs poziva funkcija koji se naziva Open Database Connectivity (ODBC)za Microsoft operativne sisteme. ODBC specifikacija ukljucuje operativnookruzenje u kome se ODBC drajveri koji su specificni za bazu podataka di-namicki ucitavaju u vreme izvrsavanja. Aplikacija se direktno linkuje sa jed-nom bibliotekom menadzera drajvera umesto sa bibliotekom za svaki SUBP.Menadzer drajvera posreduje izmedu poziva funkcija u vreme izvrsavanja ap-likacije i obezbeduje da su oni upereni ka odgovarajucem ODBC drajveru kojije specifican za odgovarajuci SUBP. S obzirom na to da su ODBC menadzerudrajvera poznate samo ODBC funkcije, funkcije koje su specificne za nekiSUBP se ne mogu koristiti u ovom okruzenju.

ODBC nije ogranicen na Microsoft operativne sisteme; postoje implemen-tacije koje su dostupne na drugim platformama.

JDBC

JDBC API (koji je slican ODBC API-ju) obezbeduje standardan nacin za pristupbazi podataka iz Java koda. Java kod prosleduje SQL naredbe kao argumentefunkcija DB2 JDBC drajveru i drajver ih dalje obraduje.

Iako sami koncepti u JDBC-u lice na one u CLI pristupu, u JDBC-u jeocigledno prisustvo objektno-orijentisane prirode Jave.

Uvod u JDBC

Prvi koraci koje moramo uciniti u cilju da koristimo JDBC jesu:

Page 34: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

34GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

• ukljucivanje linije:

import java.sql.*;

da bismo u programu pisanom na Javi imali na raspolaganju JDBC klase,

• ucitavanje drajvera za sistem baza podataka koji zelimo da koristimo.Drajver koji nam treba zavisi od toga koji SUBP nam je na raspolaganjui on se ukljucuje naredbom:

Class.forName(<ime_drajvera>);

Na primer, da bismo dobili drajver za DB2 sistem, potrebno je izvrsitinaredbu:

Class.forName("com.ibm.db2.jcc.DB2Driver");

Efekat metoda Class.forName() je da se odgovarajuca klasa ucita di-namicki (u vreme izvrsavanja programa). Od ovog momenta aplikacijije na raspolaganju klasa DriverManager. Ova klasa je po mnogo cemuslicna okruzenju ciji slog pravimo kao prvi korak u koriscenju CLI pris-tupa.

• uspostavljanje konekcije sa bazom podataka. Promenljiva klase Connectionse pravi primenom metode getConnection na DriverManager.

Naredba u Javi kojom se pravi konekcija je:

Connection mojaKonekcija = DriverManager.getConnection(<URL>,

<username>,<password>);

Svaki SUBP ima svoj nacin zadavanja URL adrese u metodu getConnection.Na primer, ako zelimo da se povezemo na DB2 bazu podataka, forma URL-aje:

"jdbc:db2://<host_name>:<port_number>/<database_name>"

JDBC objekat tipa Connection je u velikoj meri slican CLI konekciji i sluziistoj svrsi. Primenom odgovarajucih metoda na konekciju mojaKonekcija,mozemo da napravimo objekat naredbe, da smestamo SQL naredbe u okviruovog objekta, vezujemo vrednosti za parametre SQL naredbe, izvrsimo SQLnaredbe, i da pregledamo rezultujuce n-torke.

Konekcija se raskida pozivom metoda close() na objekat tipa Connection.

Page 35: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.4. UPOTREBA ODBC STANDARDA 35

Pravljenje naredbi u JDBC-u

Postoje dve metode koje mozemo primeniti na objekat tipa Connection dabismo napravili naredbu:

1. metod createStatement() vraca objekat tipa Statement. Ovom objektujos uvek nije dodeljena nijedna SQL naredba, te se on moze smatratianalognim CLI pozivu SQLAllocHandle,

2. metod prepareStatement(Q), gde je Q niska koja sadrzi naredbu SQL-ai vraca objekat tipa PreparedStatement. Stoga mozemo napraviti par-alelu izmedu ovog metoda sa primenom dva koraka u CLI pristupukojima se prvo dobija pokazivac na slog naredbe koriscenjem funkcijeSQLAllocHandle, a nakon toga na taj slog i upit Q primenjuje funkcijaSQLPrepare.

Postoje cetiri razlicita nacina na koje se moze izvrsiti naredba SQL-a. Onise medusobno razlikuju po tome da li primaju SQL naredbu kao argumentili ne, a takode prave razliku i medu SQL naredbama – da li je u pitanjuupit ili neka druga naredba koju u JDBC-u uopsteno nazivamo izmenom.Pod izmenom podrazumevamo i umetanje novih redova, kao i sve naredbekoje se odnose na shemu, kao sto je recimo CREATE TABLE. Cetiri metoda zaizvrsavanje naredbe su:

1. executeQuery(Q) koja kao argument prima nisku Q koja sadrzi upit uSQL-u i primenjuje je na objekat tipa Statement. Ovaj metod vraca ob-jekat tipa ResultSet, koji je skup n-torki u rezultatu upita Q.

2. executeQuery() koja se primenjuje na objekat tipa PreparedStatement.S obzirom na to da vec pripremljena naredba ima pridruzen upit, ovafunkcija nema argumenata. I ona vraca objekat tipa ResultSet.

3. executeUpdate(U) koja prima kao argument nisku U koja sadrzi SQLnaredbu koja nije upit i kada se primeni na objekat tipa Statement izvrsavaSQL naredbu U. Efekat ove operacije se moze uociti samo na samoj bazipodataka; ne vraca se objekat tipa ResultSet vec vraca broj redova nakoje je ta naredba uticala, odnosno 0 ako je u pitanju naredba DDL-a.

4. executeUpdate() koja nema argument i primenjuje se na vec pripreml-jenu naredbu. U ovom slucaju izvrsava se SQL naredba koja je pridru-zena naredbi. SQL naredba ne sme biti upit.

Pretpostavimo da imamo objekat mojaKonekcija koji je tipa Connection ida zelimo da izvrsimo upit:

SELECT god_izdavanja, izdavac FROM Knjiga

Jedan nacin da to uradimo jeste da napravimo objekat naredba upit tipaStatement i da ga iskoristimo da bismo direktno izvrsili upit:

Statement upit1 = mojaKonekcija.createStatement();

ResultSet godine_i_izdavaci = upit1.executeQuery(

"SELECT god_izdavanja, izdavac FROM Knjiga");

Page 36: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

36GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

Rezultat upita je objekat tipa ResultSet koji smo imenovali godine i izdavaci.Videcemo u nastavku kako da izdvojimo n-torke iz objekta godine i izdavaci

i kako da ih obradimo.S druge strane, mozemo prvo pripremiti upit a da ga naknadno izvrsimo.

Ovaj pristup je pogodniji ako zelimo da isti upit izvrsimo veci broj puta. Utom slucaju ima smisla jednom pripremiti upit, a onda ga vise puta izvrsavati,umesto da SUBP svaki put prilikom izvrsavanja iznova priprema isti upit.Koraci u JDBC-u kojima se ovo postize su sledeci:

PreparedStatement upit2 = mojaKonekcija.prepareStatement(

"SELECT god_izdavanja, izdavac FROM Knjiga");

ResultSet godine_i_izdavaci = upit2.executeQuery();

Ako pak zelimo da izvrsimo naredbu koja nije upit i koja nema param-etara, mozemo da izvedemo analogne korake. Ipak, u ovom slucaju ne pos-toji rezultujuci skup. Pretpostavimo da zelimo da dodamo novu knjigu utabelu Knjiga. Mozemo napraviti naredbu naredba dodaj i izvrsiti je na obaprethodna nacina:

Statement dodaj1 = mojaKonekcija.createStatement();

int brRedova = dodaj1.executeUpdate("INSERT INTO Knjiga

VALUES(111,’Na Drini cuprija’,’Zavod za udzbenike’,2009)");

System.out.println("Broj dodatih redova: " + brRedova);

ili:

PreparedStatement dodaj2 = mojaKonekcija.prepareStatement(

"INSERT INTO Knjiga VALUES(111,’Na Drini cuprija’, " +

" ’Zavod za udzbenike’,2009)");

int brRedova = dodaj2.executeUpdate();

System.out.println("Broj dodatih redova: " + brRedova);

Primetimo da je u drugoj naredbi iskoriscen Java operator + za konkate-naciju stringova. Stoga smo u mogucnosti da naredbu SQL-a pisemo u viseredova ako je potrebno.

Kada naredba vise nije potrebna dobra praksa je zatvoriti je pozivom metodaclose().

Operacije nad kursorima u JDBC-u

Kada izvrsavamo upit i dobijemo skup redova u rezultatu, mozemo pokrenutikursor kroz n-torke u skupu rezultata. Klasa ResultSet raspolaze narednimmetodama:

• next() – kada se ovaj metod primeni na objekat tipa ResultSet, uzrokujeda se implicitni kursor pomeri na sledecu n-torku (odnosno na prvu akose prvi put primenjuje). Ova metoda vraca FALSE ako nema naredne n-torke.

• getString(i), getInt(i), getFloat(i) i analogne metode za drugetipove koje SQL vrednosti mogu da imaju – svaka od ovih metoda vracai-tu komponentu n-torke na koju kursor trenutno ukazuje; pritom semora koristiti metod koji je odgovarajuci za tip i-te komponente.

Page 37: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.4. UPOTREBA ODBC STANDARDA 37

• close() – zatvara se objekat tipa ResultSet; skup rezultata se i au-tomatski zatvara ako se zatvori naredba za koju je vezan

• wasNull() – proverava da li je poslednja procitana vrednost iz rezul-tujuceg skupa bila NULL

Ako smo u prethodnom primeru dobili rezultujuci skup godine i izdavaci,moguce je redom pristupiti njenim n-torkama i izvrsiti odgovarajucu obradu.Podsetimo se da se ove n-torke sastoje od dve komponente od kojih je jednacelobrojnog tipa, a druga niska. Dakle, format petlje bio bi sledeci:

while(godine_i_izdavaci.next()){

int godina = godine_i_izdavaci.getInt(1);

System.out.println("godina" + godina);

String izdavac = godine_i_izdavaci.getString(2);

if (godine_i_izdavaci.wasNull())

System.out.println("izdavac je nepoznat");

else

System.out.println("izdavac" + izdavac);

};

godine_i_izdavaci.close();

Podrazumevano, kursorom se u JDBC pristupu moze kretati samo una-pred. Medutim, mogu se definisati i kursori kojima se moze kretati i un-apred i unazad, navodenjem odgovarajucih vrednosti kao argumenta funkcijeprepareStatement(). Onda je moguce npr. metodom afterLast() primen-jenim na ResultSet pozicionirati se nakon svih redova u rezultatu, pa napre-dovati ka pocetku pozivom metoda previous(). Kursor se moze definisatitako da sluzi i za azuriranje, navodenjem odgovarajucih parametara u okvirunaredbe prepareStatement().

Prosledivanje parametara

Kao i u CLI pristupu, moguce je navesti znak pitanja umesto dela upita, i ondavezati vrednosti za ove parametre. Da bismo ovo uradili u JDBC-u, potrebnoje napraviti pripremljenu naredbu, a zatim na tu naredbu primeniti metod kaosto je recimo setString(i,v) ili setInt(i,v) koji vezuje vrednost v; pritomvrednost v mora biti odgovarajuceg tipa u odnosu na primenjeni metod zai-ti parametar upita. Na ovaj nacin moguce je proslediti i NULL vrednostparametra, npr. sa setString(1,null);

Pokusajmo da imitiramo CLI kod u kome smo pripremili naredbu za u-metanje nove knjige u relaciju Knjiga, sa parametrima za sifru i naziv knjige.Odgovarajuci Java kod sledi u nastavku.

PreparedStatement naredba_insert_param = mojaKonekcija.prepareStatement(

"INSERT INTO Knjiga(k_sifra,naziv) VALUES(?,?)");

...

/* ovde ide ucitavanje vrednosti u promenljive

Page 38: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

38GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

sifra_knjige i naziv_knjige */

...

naredba_insert_param.setString(1,sifra_knjige);

naredba_insert_param.setString(2,naziv_knjige);

naredba_insert_param.executeUpdate();

2.5 Zapamcene procedure

U ovom poglavlju upoznacemo se sa pojmom zapamcenih procedura (engl.stored procedures). One omogucavaju pisanje procedura u jednostavnomjeziku opste namene i njihovo pamcenje u bazi podataka, kao dela sheme.U tom slucaju se one mogu koristiti u SQL upitima i drugim naredbama zaizracunavanja koja se ne mogu uraditi samo pomocu SQL-a. Ovde cemoopisati SQL/PSM standard (engl. Persistant Stored Modules) kojim se definiseprosirenje SQL-a konstruktima iz proceduralnih jezika za koriscenje u zapam-cenim procedurama.

Zapamcena procedura je programski blok koji se poziva iz aplikacije naklijentu a izvrsava se na serveru baza podataka. Pise se u odgovarajucimprosirenjima SQL-a, kao sto je, na primer, C-Java/SQL u DB2, kompilira ipamti u biblioteci odgovarajuceg SUBP. Tako se primenom zapamcenih pro-cedura deo logike aplikacije prenosi sa klijenta na server, i povecava se funk-cionalnost servera. Najcesci razlog za koriscenje zapamcenih procedura jeintenzivna obrada podataka iz baze podataka koja proizvodi malu kolicinurezultujucih podataka, ili cinjenica da je skup operacija (koje se izdvajaju uzapamcenu proceduru) zajednicki za vise aplikacija.

Zapamcene procedure ostvaruju mnoge prednosti:

1. koriste prednosti mocnih servera;

2. donose poboljsanja performansi statickom SQL-u;

3. smanjuju mrezni saobracaj;

4. poboljsavaju integritet podataka dopustanjem raznim aplikacijama dapristupe istom programskom kodu.

Pravljenje PSM funkcija i procedura

U PSM-u definisu se moduli koji predstavljaju kolekcije definicija procedura ifunkcija, deklaracija privremenih relacija i jos nekih opcionih deklaracija.

Procedura se definise na sledeci nacin:

CREATE PROCEDURE <naziv>(<parametri>)

<lokalne_deklaracije>

<telo_procedure>;

Funkcija se definise na slican nacin, osim sto se koristi kljucna rec FUNCTIONi sto postoji povratna vrednost koja se mora zadati.

CREATE FUNCTION <naziv>(<parametri>) RETURNS <tip>

<lokalne_deklaracije>

<telo_funkcije>;

Page 39: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.5. ZAPAMCENE PROCEDURE 39

Parametri PSM procedure se ne zadaju samo svojim nazivom i tipom,vec im prethodi i naziv moda, koji moze biti IN za parametre koji su samoulazni, OUT za parametre koji su samo izlazni, odnosno INOUT za parametrekoji su i ulazni i izlazni. Podrazumevana vrednost je IN i moze se izostaviti.S druge strane, parametri funkcije mogu biti samo ulazni. To znaci da PSMzabranjuje bocne efekte funkcija, te je jedini nacin da dobijemo informacijuod funkcije putem njene povratne vrednosti. Necemo navoditi IN mod zaparametre funkcija, a hocemo u procedurama.

U okviru tela procedure i funkcije moze se naci veliki broj razlicitih naredbi,izmedu ostalog i SQL naredbe. Od upita moze se naci onaj koji vraca tacnojedan red u rezultatu ili se mora pristupati koriscenjem kursora.

Prikazimo PSM proceduru koja kao argumente ima dva naziva izdavaca:stari i novi i zamenjuje sve pojave starog naziva izdavaca u tabeli Knjiganovim nazivom.

CREATE PROCEDURE Zameni(IN stari_izdavac char(30),

IN novi_izdavac char(30))

UPDATE Knjiga

SET izdavac = novi_izdavac

WHERE izdavac = stari_izdavac;

Ova procedura ima dva parametra, oba su niske duzine 30 karaktera, stoje u skladu sa tipom atributa izdavac u tabeli Knjiga. Imena parametara semogu koristiti kao da su konstante i vazi da parametri i lokalne promenljivePSM procedura i funkcija nemaju dvotacku ispred svog naziva.

Neke jednostavne forme naredbi u PSM

Nabrojimo neke jednostavne naredbe:

1. naredba poziva: Forma poziva procedure je:

CALL <naziv_procedure>(<lista argumenata>);

Ovaj poziv se moze javiti kao deo programa na maticnom jeziku. Rec-imo prethodnu proceduru bismo mogli da pozovemo sa:

EXEC SQL CALL Zameni(’Prosveta’,’Nova prosveta’);

ili

EXEC SQL CALL Zameni(’Prosveta’,:x);

Poziv procedure se moze naci i kao deo neke druge PSM funkcije ili pro-cedure. Primetimo da funkciju nije moguce pozvati na ovaj nacin vec sefunkcija poziva, kao i u C-u, navodenjem njenog naziva i odgovarajuceliste argumenata u okviru nekog izraza.

2. naredba vracanja vrednosti: njena forma je:

Page 40: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

40GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

RETURN <izraz>;

Ova naredba se moze javiti samo u funkciji. Ona izracunava vrednostizraza i postavlja povratnu vrednost funkcije na tu vrednost. Medutim,za razliku od standardnih programskih jezika, ova naredba ne prekidaizvrsavanje funkcije. Stavise, izvrsavanje funkcije se nastavlja pocevsiod naredne naredbe i moguce je da ce povratna vrednost biti izmenjenapre nego sto se funkcija zavrsi.

3. deklaracija lokalnih promenljivih: naredba oblika:

DECLARE <naziv> <tip>;

deklarise promenljivu datog tipa sa datim nazivom. Ova promenljiva jelokalna i njena vrednost se ne cuva od strane SUBP-a nakon izvrsavanjafunkcije ili procedure. Deklaracije moraju da prethode izvrsnim nared-bama u telu funkcije ili procedure.

4. naredbe dodele: Dodela ima naredni oblik:

SET <promenljiva> = <izraz>;

Osim pocetne reci SET dodela u PSM-u je nalik dodeli u drugim jezicima.Izracunava se vrednost izraza sa desne strane jednakosti i ta vrednost sedodeljuje promenljivoj sa leve strane znaka jednakosti. Dozvoljeno jeda vrednost izraza bude NULL. Sta vise, izraz moze biti i upit ukolikovraca tacno jednu vrednost.

5. grupe naredbi: Mozemo formirati listu naredbi koje se zavrsavaju tackomi zarezom i koje su ogradene kljucnim recima BEGIN i END. Ovaj kon-strukt se tretira kao jedinstvena naredba i moze se javiti svuda gde semoze javiti jedna naredba. Na primer, posto se za telo procedure ilifunkcije ocekuje jedinstvena naredba, moguce je u telo staviti proizvol-jan niz naredbi i ograditi ih kljucnim recima BEGIN i END.

6. imenovanje naredbi: naredbu mozemo imenovati tako sto joj kao prefiksnavedemo ime i stavimo dvotacku.

Naredbe grananja

U zapamcenim procedurama podrzano je grananje koriscenjem naredbe IF.Ona se razlikuje od jezika C u narednim tackama:

• naredba se zavrsava kljucnim recima END IF;

• IF naredba koja je umetnuta u ELSE klauzu se uvodi jedinstvenom kljuc-nom recju ELSEIF.

Stoga je opsta forma naredbe IF sledeca:

Page 41: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.5. ZAPAMCENE PROCEDURE 41

IF <uslov> THEN

<lista_naredbi>

ELSEIF <uslov> THEN

<lista_naredbi>

ELSEIF

...

[ELSE

<lista_naredbi>]

END IF;

Uslov je proizvoljni logicki izraz. Poslednji ELSE i njegova lista naredbi suopcioni.

U nastavku je dat kod funkcije koja uzima kao argumente naziv izdavacai i godinu g i vraca logicku vrednost TRUE ako i samo ako je izdavac i izdaobar jednu knjigu u godini g ili ako u toku te godine nije izdata nijedna knjiga.

CREATE FUNCTION IzdaoUGod(i CHAR(30), g SMALLINT) RETURNS BOOLEAN

IF NOT EXISTS(

SELECT * FROM Knjiga WHERE god_izdavanja = g)

THEN RETURN TRUE;

ELSEIF 1 <=

(SELECT COUNT(*) FROM Knjiga WHERE god_izdavanja = g AND

izdavac = i)

THEN RETURN TRUE;

ELSE RETURN FALSE;

END IF;

Upiti u PSM-u

Postoji nekoliko nacina na koje se upiti mogu koristiti u okviru PSM-a:

1. upiti se mogu koristiti u uslovima, odnosno u opstem slucaju na svakommestu gde se u SQL-u moze naci podupit (u prethodnom kodu videlismo dva primera upotrebe podupita).

2. upiti koji vracaju jednu vrednost mogu se koristiti sa desne strane naredbedodele.

3. upit koji vraca tacno jedan red je legalna naredba u PSM-u. Podse-timo se da ova naredba ima INTO stavku kojom se zadaju promenljiveu koje se smestaju komponente te jedinstvene n-torke koja se vraca. Ovepromenljive mogu biti lokalne promenljive ili parametri PSM procedure.

4. mozemo deklarisati i koristiti kursor, isto kao kod ugradenog SQL-a.Jedina razlika je u tome sto se ne javlja EXEC SQL na pocetku naredbe ipromenljive ne koriste dvotacku kao prefiks.

Na primer, mozemo napisati proceduru koja sadrzi naredbu SELECT INTO

na sledeci nacin:

Page 42: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

42GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

CREATE PROCEDURE Obrada_knjige(IN sifra_knjige INTEGER)

DECLARE naziv_knjige CHAR(50);

BEGIN

SELECT naziv INTO naziv_knjige

FROM Knjiga

WHERE k_sifra = sifra_knjige;

...

/* ovde ide dalja obrada naziva knjige */

...

END

Isti efekat bismo mogli da postignemo i na drugaciji nacin:

CREATE PROCEDURE Obrada_knjige(IN sifra_knjige INTEGER)

DECLARE naziv_knjige CHAR(50);

BEGIN

SET naziv = (SELECT naziv FROM Knjiga

WHERE k_sifra = sifra_knjige);

...

/* ovde ide dalja obrada naziva knjige*/

...

END

Petlje u PSM-u

Osnovna konstrukcija za petlju je oblika:

LOOP

<lista_naredbi>

END LOOP;

Petlja se cesto imenuje da bi se iz nje moglo izaci koriscenjem naredbe:

LEAVE <naziv_petlje>;

Najcesce se u petlji citaju n-torke koriscenjem kursora i iz petlje je potrebnoizaci kada vise nema n-torki u rezultatu upita. Korisno je uvesti naziv zauslov na vrednost promenljive SQLSTATE koji ukazuje da nijedna n-torka nijeprocitana (za vrednost ’02000’). To je moguce uraditi na sledeci nacin:

DECLARE Not_Found CONDITION FOR SQLSTATE ’02000’;

U opstem slucaju mozemo deklarisati uslov sa proizvoljnim imenom kojiodgovara proizvoljnoj vrednosti promenljive SQLSTATE:

DECLARE <naziv> CONDITION FOR SQLSTATE <vrednost>;

Page 43: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.5. ZAPAMCENE PROCEDURE 43

Napisimo sad proceduru koja ima ulazni argument naziv izdavaca i i imaizlazne argumente sr vrednost i varijansa koji na kraju izvrsenja proceduretreba da sadrze srednju vrednost i varijansu godina izdavanja svih knjiga kojeje izdao izdavac i.

CREATE PROCEDURE SrVredVar(IN i CHAR(30),

OUT sr_vrednost REAL, OUT varijansa REAL)

DECLARE Not_Found CONDITION FOR SQLSTATE ’02000’;

DECLARE KnjigeKursor CURSOR FOR

SELECT god_izdavanja FROM Knjige WHERE izdavac = i;

DECLARE nova_god SMALLINT;

DECLARE broj_knjiga INTEGER;

BEGIN

SET sr_vrednost = 0.0;

SET varijansa = 0.0;

SET broj_knjiga = 0;

OPEN KnjigeKursor;

knjigePetlja: LOOP

FETCH KnjigeKursor INTO nova_god;

IF Not_Found THEN LEAVE knjigePetlja END IF;

SET broj_knjiga = broj_knjiga + 1;

SET sr_vrednost = sr_vrednost + nova_god;

SET varijansa = varijansa + nova_god * nova_god;

END LOOP;

SET sr_vrednost = sr_vrednost/broj_knjiga;

SET varijansa = varijansa/broj_knjiga - sr_vrednost * sr_vrednost;

CLOSE KnjigeKursor;

END;

For petlja

U PSM-u postoji i FOR petlja, ali se ona koristi samo za iteriranje kroz kursor.Naredba FOR petlje ima sledeci oblik:

FOR [<naziv_petlje> AS] [<naziv_kursora> CURSOR FOR]

<upit>

DO

<lista_naredbi>

END FOR;

Ova naredba ne samo da deklarise kursor vec nas oslobada velikog brojatehnickih detalja: otvaranja i zatvaranja kursora, citanja podataka i provereda li vise nema n-torki za citanje. Ipak, s obzirom na to da ne citamo samipodatke, ne mozemo zadati promenljive u koje treba smestiti komponenten-torke. Stoga se imena koja se koriste za atribute u rezultatu upita takode

Page 44: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

44GLAVA 2. NACINI KORISCENJA BAZA PODATAKA U VISIM

PROGRAMSKIM JEZICIMA

tretiraju od strane PSM-a kao lokalne promenljive istog tipa. Ukoliko se nezada naziv kursora, DB2 ce automatski generisati jedinstveni naziv kursora zainterne potrebe. Na kursor koji je deklarisan u FOR petlji se ne moze referisativan petlje: dakle poziv naredbe OPEN, FETCH ili CLOSE rezultovace greskom. Uokviru FOR petlje moze se javiti naredba LEAVE, ali onda se kompletna petljamora imenovati.

Zapisimo prethodni primer koriscenjem for petlje. Mnoge stvari se nemenjaju: deklaracija procedure je ista, kao i deklaracija lokalne promenljive.Ipak, nije potrebno da deklarisemo kursor u sekciji za deklaraciju procedureniti da definisemo uslov kad podaci nisu nadeni. Primetimo da se podatkugod izdavanja pristupa preko naziva atributa, a ne preko neke nove lokalnepromenljive.

CREATE PROCEDURE SrVredVar(IN i CHAR(30),

OUT st_vrednost REAL, OUT varijansa REAL)

DECLARE br_knjiga INTEGER;

BEGIN

SET sr_vrednost = 0.0;

SET varijansa = 0.0;

SET br_knjiga = 0;

FOR knjigePetlja AS KnjigeKursor CURSOR FOR

SELECT god_izdavanja FROM Knjige WHERE izdavac = i;

DO

SET br_knjiga = br_knjiga + 1;

SET sr_vrednost = sr_vrednost + god_izdavanja;

SET varijansa = varijansa + god_izdavanja * god_izdavanja;

END FOR;

SET sr_vrednost = sr_vrednost/br_knjiga;

SET varijansa = varijansa/br_knjiga - sr_vrednost * sr_vrednost;

END;

Izuzeci u PSM-u

SQL sistem nam ukazuje na potencijalne greske postavljanjem nenula nizavrednosti u string SQLSTATE. Videli smo primer ovog koda: kod ’02000’ukazuje da nije pronadena nijedna n-torka, dok npr kod ’21000’ ukazuje daje SELECT koji vraca jedan red vratio vise od jednog reda.

PSM nam omogucava da deklarisemo deo koda, koji nazivamo hvatacizuzetka (engl. exception handler) koji se poziva uvek kada se jedan od kodovaiz date liste javi u promenljivoj SQLSTATE tokom izvrsavanja naredbe ili listenaredbi. Svaki hvatac izuzetaka je vezan za neki blok koda, ogradenim saBEGIN i END. Hvatac se javlja u okviru ovog bloka i primenjuje se samo nanaredbe u ovom bloku. Njegove komponente su:

1. lista uslova izuzetaka za koje se poziva hvatac,

2. kod koji se izvrsava kada se uhvati neki od pridruzenih izuzetaka,

Page 45: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

2.5. ZAPAMCENE PROCEDURE 45

3. naznaka gde treba ici nakon sto je hvatac zavrsio posao.

Deklaracija hvataca izuzetaka ima sledeci oblik:

DECLARE <gde_ici_nakon> HANDLER FOR <lista_uslova>

<naredba>

Podrzane su naredne vrednosti za to gde ici nakon obrade izuzetka:

1. CONTINUE – oznacava da se nakon izvrsavanja naredbe iz tela deklaracijehvataca, izvrsava naredba nakon one koja je proizvela izuzetak,

2. EXIT – oznacava da se nakon izvrsavanja naredbe iz tela deklaracijehvataca izlazi iz bloka oznacenog sa BEGIN i END i izvrsava se prva naredbanakon ovog bloka,

3. UNDO – ima isto znacenje kao EXIT, osim sto se ponistavaju sve izmene nabazi podataka ili lokalnim promenljivim koje su izvele naredbe iz ovogbloka.

U listi uslova se mogu naci ili deklarisani uslovi (npr. Not found) ili izrazikoji ukljucuju promenljivu SQLSTATE i niske duzine 5.

Pogledajmo primer PSM funkcije koja kao argument uzima naziv knjige ivraca godinu u kojoj je knjiga izdata. Ako ne postoji knjiga sa datim nazivomili postoji vise knjiga sa datim nazivom, potrebno je vratiti NULL.

CREATE FUNCTION IzracunajGodinu(n CHAR(50)) RETURNS SMALLINT

DECLARE Not_Found CONDITION FOR SQLSTATE ’02000’;

DECLARE Too_Many CONDITION FOR SQLSTATE ’21000’;

BEGIN

DECLARE EXIT HANDLER FOR Not_Found, Too_Many

RETURN NULL;

RETURN (SELECT god_izdavanja FROM Knjiga WHERE naziv = n);

END;

Page 46: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se
Page 47: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Glava 3

Transakcije

3.1 Transakcija i integritet

Transakcija je logicka jedinica posla pri radu sa podacima. Ona predstavljaniz radnji koji ne narusava uslove integriteta. Sa stanovista korisnika, izvrsa-vanje transakcije je atomicno.

Po izvrsenju kompletne transakcije stanje baze treba da bude konzistentno,tj. da su ispunjeni uslovi integriteta. Dakle, posmatrana kao jedinica posla,transakcija prevodi jedno konzistentno stanje baze u drugo takvo stanje baze,dok u medukoracima transakcije konzistentnost podataka moze biti i narusena.Transakcija na taj nacin predstavlja i bezbedno sredstvo za interakciju koris-nika sa bazom.

U sistemu DB2, za sadrzaj transakcije i proveru uslova integriteta odgov-oran je programer, tj. sama aplikacija treba da obezbedi vazenje uslova in-tegriteta. Uobicajeno je da u radu sa transakcijama SUBP koristi usluge dru-gog sistema – upravljaca transakcija (engl. transaction manager). Sistem zaupravljanje transakcijama obezbeduje da se, bez greske, upisuju u bazu po-dataka ili efekti izvrsenja svih radnji od kojih se transakcija sastoji, ili nijedneradnje. Na ovaj nacin je omogucen jedan aspekt kontrole konzistentnosti baze.

RSUBP DB2 koristi dve radnje upravljaca transakcija: to su COMMIT i ROLLBACK(to su ujedno i iskazi SQL-a), od kojih svaka oznacava i kraj transakcije: COMMIToznacava uspesan kraj transakcije i trajan upis efekata svih radnji transakcijeu bazu, dok ROLLBACK oznacava neuspesan kraj transakcije i ponistenje svihefekata koje su proizvele radnje te transakcije.

U sistemu DB2 transakcija je deo aplikacije od pocetka programa do prveradnje COMMIT ili ROLLBACK, odnosno izmedu dve susedne takve radnje u pro-gramu, odnosno od poslednje takve radnje do kraja programa. Ako se nijednaod radnji COMMIT, ROLLBACK ne ukljuci u program, onda citav program pred-stavlja jednu transakciju; na kraju programa se sistemski generise jedna ko-manda COMMIT ako je kraj programa uspesan, odnosno jedna komanda ROLLBACKako je kraj programa neuspesan. Ugnjezdene transakcije u sistemu DB2 nisumoguce.

47

Page 48: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

48 GLAVA 3. TRANSAKCIJE

Na primer, deo programa u aplikativnom SQL-u kojim se realizuje transak-cija u sistemu DB2 kojom se 100 dinara prebacuje sa racuna sa sifrom R102 naracun sa sifrom R203 i kojom se odrzava dati uslov integriteta nad relacijomRacun mogao bi da ima naredni izgled:

EXEC SQL WHENEVER SQLERROR GOTO PONISTI;

EXEC SQL UPDATE Racun

SET Stanje = Stanje - 100

WHERE R_sifra = ’R102’;

EXEC SQL UPDATE Racun

SET Stanje = Stanje + 100

WHERE R_sifra = ’R203’;

EXEC SQL COMMIT;

GOTO ZAVRSENA;

PONISTI: EXEC SQL ROLLBACK;

ZAVRSENA: RETURN;

3.2 Konkurentnost

Kako bazu podataka istovremeno koristi veci broj korisnika, nad bazom po-dataka se istovremeno moze izvrsavati veci broj transakcija. Prednosti konku-rentnog (istovremenog) rada transakcija jeste krace vreme odziva, kao i vecapropusnost.

Mada svaka od transakcija moze ispunjavati uslove integriteta baze po-dataka, ponekad njihovo istovremeno izvrsavanje moze da narusi te uslove.Pod izvrsenjem skupa transakcija ovde se podrazumeva niz radnji od kojihse te transakcije sastoje. U tom nizu redosled radnji iz svake transakcije je ne-promenjen, ali dve uzastopne radnje ne moraju pripadati istoj transakciji. Kaoosnovne komponente transakcije posmatracemo objekte (npr. slogove) i dveradnje: citanje i upis (tj. azuriranje). Dve radnje u ovom modelu su konfliktneako se obavljaju nad istim objektom a jedna od njih je radnja upisa. To znaci daparovi konfliktnih radnji mogu biti samo parovi (citanje, upis) i (upis, upis).

Problem kojim cemo se u nastavku baviti jeste kako obezbediti da kon-kurentne transakcije ne “smetaju” jedna drugoj i kako obezbediti da njihovokonkuretno izvrsavanje ostavi bazu podataka u konzistentnom stanju.

Problemi pri konkuretnom radu

Pri konkurentnom izvrsavanju skupa transakcija mogu nastati sledeci prob-lemi:

1. problem izgubljenih azuriranja (engl. lost update problem)

2. problem zavisnosti od nepotvrdenih podataka (engl. uncommited depen-dency problem)

Page 49: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.2. KONKURENTNOST 49

3. problem nekonzistentne analize (engl. inconsistent analysis problem)

Problem izgubljenih azuriranja

Neka se svaka od od transakcija A i B sastoji od citanja i upisa istog sloga da-toteke, pri cemu transakcije A i B najpre citaju podatke, a zatim vrse upis uistom redosledu. Na primer, transakcija A cita slog koji se odnosi na knjigu sasifrom k sifra=301, zatim transakcija B cita isti slog (obe transakcije citaju istepodatke; konkretno za vrednost atributa god izdavanja citaju recimo vred-nost 1990). Posle toga transakcija A menja vrednost atributa god izdavanja

tog sloga (sa 1990 na 1995) i zavrsava sa radom, npr. zatvara datoteku, a zatimtransakcija B menja vrednost atributa god izdavanja (sa procitane vrednosti1990 na 2000) i zavrsava sa radom (npr. zatvara svoju verziju iste datoteke).Kakav je efekat rada ove dve transakcije? Ostaju zapamcene samo promenetransakcije B koja je poslednja izvrsila upis i zatvorila datoteku, a transakcijiA se bez obavestenja ponistava efekat upisa, tj. gubi se vrednost 1995 atributagod izdavanja posmatranog sloga.

T Transakcija A Transakcija B... ... ...t1 FETCH R —-t2 —- FETCH Rt3 UPDATE R —-t4 —- UPDATE R

Tabela 3.1: Problem izgubljenih azuriranja

Problem zavisnosti od nepotvrdenih podataka

Pretpostavimo da transakcija A ukljucuje citanje nekog sloga R, a da transak-cija B ukljucuje azuriranje istog sloga. Neka pri konkurentnom izvrsavanjuovih transakcija najpre transakcija B azurira slog R, a zatim transakcija Aprocita slog R i zavrsi svoje izvrsavanje. U nekom kasnijem trenutku, iz nekograzloga, transakcija B ponisti sve efekte koje je do tog trenutka proizvela nabazu, tj. ponisti azuriranje sloga R. U tom slucaju transakcija A procitala jeazuriranu vrednost sloga R koja nije ni trebalo da bude upisana u bazu.

T Transakcija A Transakcija B... ... ...t1 —- UPDATE Rt2 FETCH R —-t3 —- ROLLBACK

Tabela 3.2: Problem zavisnosti od nepotvrdenih podataka (slucaj (a))

Slicno, neka transakcija A ukljucuje azuriranje sloga R, a neka se transak-cija B sastoji od istih radnji kao u prethodnom slucaju. Pri istom redosledu

Page 50: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

50 GLAVA 3. TRANSAKCIJE

izvrsavanja radnji i ponistenju transakcije B izgubilo bi se, bez obavestenja,azuriranje transakcije A, jer bi ponistavanjem efekata transakcije B vrednostsloga R bila vracena na vrednost pre azuriranja (od strane transakcije A).

T Transakcija A Transakcija B... ... ...t1 —- UPDATE Rt2 UPDATE R —-t3 —- ROLLBACK

Tabela 3.3: Problem zavisnosti od nepotvrdenih podataka (slucaj (b))

Problem nekonzistentne analize

Pretpostavimo da imamo dve transakcije koje rade nad tri bankovna racuna,pritom transakcija A sabira stanje na sva tri racuna, dok transakcija B prenosi1000 dinara sa treceg racuna na prvi. Na racunu Rac1 nalazi se 4000 dinara, naracunu Rac2 nalazi se 5000 dinara, a na racunu Rac3 3000 dinara. Ukoliko setransakcija B u potpunosti izvrsi izmedu radnji citanja stanja na racunu Rac1

i citanja stanja na racunu Rac3 transakcije A, baza ce nakon izvrsenja ove dvetransakcije biti u nekonzistentnom stanju (u navedenom slucaju transakcija Abi dobila kao zbir stanja na sva tri racuna 11000 dinara umesto 12000 dinara).

T Transakcija A Transakcija B... ... ...t1 FETCH Rac1 (4000), sum=4000 —-t2 FETCH Rac2 (5000), sum=9000 —-t3 —- FETCH Rac3 (3000)t4 —- UPDATE Rac3 (3000→2000)t5 —- FETCH Rac1 (4000)t6 —- UPDATE Rac1 (4000→5000)t7 —- COMMITt8 FETCH Rac3 (2000), sum=11000 —-

Tabela 3.4: Problem nekonzistentne analize

Problemi izgubljenih azuriranja i nekonzistentne analize vezani su za re-dosled konkurentnog izvrsavanja radnji dve ili vise transakcija. Problem zav-isnosti od nepotvrdenih podataka je, osim za konkurentnost, vezan i za opo-ravak baze podataka nakon ponistavanja transakcije pri konkurentnom izvr-senju. Do ponistenja transakcije moze doci, na primer, zbog greske u transak-ciji ili zbog pada sistema.

Sva tri navedena problema bice resavana koriscenjem mehanizma zaklju-cavanja (engl. locking). Mehanizam zakljucavanja obezbeduje konkurentnoizvrsenje skupa transakcija koje je ekvivalentno serijskom izvrsenju transakcija– kada se transakcije izvrsavaju jedna za drugom. Za serijsko izvrsavanje vazi

Page 51: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.2. KONKURENTNOST 51

da ne narusava integritet i konzistentnost baze ako to isto vazi za svaku poje-dinacnu transakciju u posmatranom skupu transakcija.

Zakljucavanje

Zakljucavanje podrazumeva postavljanje katanaca na objekat. Ideja zaklju-cavanja je sledeca: kada transakcija zeli da radi sa nekim resursom ona za-hteva zakljucavanje tog objekta (postavlja katanac nad tim objektom), a kadase transakcija zavrsi taj resurs se oslobada.

Pretpostavimo da sistem podrzava bar dve vrste katanaca:

• deljivi (S – Share) katanac i

• privatni ili ekskluzivni (X – eXclusive) katanac.

S katanac je potreban za citanje, a X katanac za azuriranje. Ako je transakcijaA postavila X katanac nad vrstom t tada zahtev bilo koje druge transakcijeB za postavljanje bilo kog katanca nad t biva odbijen. Ako je transakcija Apostavila S katanac nad vrstom t tada zahtev bilo koje druge transakcije B zapostavljanje S katanca nad t moze biti ispunjen, dok zahtev za postavljanje Xkatanca nad t biva odbijen.

Transakcija AX S -

Transakcija BX N N DS N D D- D D D

Tabela 3.5: Matrica kompatibilnosti nacina zakljucavanja; X oznacava ek-skluzivni katanac, S deljivi, a ’-’ da ne postoji katanac; D oznacava da transak-cija moze dobiti zeljeni katanac, a N da ne moze.

Dvofazni protokol zakljucavanja (eng. two-phase locking) podrazumevada se izvrsavanje svake transakcije sastoji iz dve faze: faze zakljucavanja ob-jekta i faze otkljucavanja objekta i te dve faze se izvrsavaju jedna za dru-gom (serijski). U fazi zakljucavanja nema nijedne radnje otkljucavanja ob-jekta, dok u fazi otkljucavanja vise nema radnji zakljucavanja (ali naravno obeove faze u sebi ukljucuju i druge operacije kao sto su citanje, upis, itd). Fazaotkljucavanja objekata zapocinje prvom radnjom otkljucavanja. Postovanjeovog protokola garantuje da se navedeni problemi konkurentnosti nece javiti.

Striktni dvofazni protokol zakljucavanja se pridrzava dvofaznog pro-tokola zakljucavanja i, dodatno, u ovom protokolu se ekskluzivni katanci o-slobadaju tek nakon kraja transakcije. Na ovaj nacin se garantuje da su sviobjekti izmenjeni od strane transakcije koja jos nije potvrdila svoje izmene,zakljucani ekskluzivnim katancem sve dok transakcija ne uradi COMMIT, o-nemogucavajuci druge transakcije da procitaju izmenjene podatke koji nisupotvrdeni.

Dakle, striktni dvofazni protokol se sastoji od narednih koraka:

1. Transakcija koja zeli da procita neku vrstu mora prvo da nad njom postavideljivi (S) katanac

Page 52: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

52 GLAVA 3. TRANSAKCIJE

2. Transakcija koja zeli da azurira neku vrstu mora prvo da nad njom po-stavi ekskluzivni (X) katanac. Alternativno, ako vec drzi S katanac nadtom vrstom, transakcija mora da zahteva unapredenje S katanca u Xkatanac

3. Ako je zahtev za postavljanjem katanca od strane transakcije B odbijenjer je u konfliktu sa vec postavljenim katancem od strane transakcije A,transakcija B ide u stanje cekanja. Transakcija B ceka dok transakcijaA ne oslobodi katanac (sistem mora da garantuje da transakcija B necezauvek da ostane u stanju cekanja)

4. Ekskluzivni katanac se zadrzava do kraja transakcije (naredbe COMMIT iliROLLBACK). Deljivi katanac se, uobicajeno, zadrzava (najduze) do krajatransakcije.

Kazemo da je izvrsavanje datog skupa transakcija korektno ako je serijal-izabilno, tj. ako proizvodi isti rezultat kao i serijsko izvrsavanje istog skupatransakcija. Efekat zakljucavanja jeste da isforsira serijalizabilnost transak-cija. Vazi sledeca teorema: ako sve transakcije primenjuju dvofazni protokolzakljucavanja, tada su svi moguci rasporedi izvrsavanja transakcija serijaliz-abilni.

Resenje navedenih problema konkurentnosti

Videcemo sada kako problemi koje smo naveli da su moguci prilikom konkurentnograda transakcija mogu biti reseni koriscenjem dvofaznog protokola zakljucavanja.

Resenje problema izgubljenih azuriranja

T Transakcija A Transakcija B... ... ...t1 FETCH R (zahteva S katanac nad R) —-t2 —- FETCH R (zahteva S katanac nad R)t3 UPDATE R (zahteva X katanac nad R) —-t4 ceka UPDATE R (zahteva X katanac nad R)t5 ceka ceka

Tabela 3.6: Problem izgubljenih azuriranja - resenje

U trenutku t1 transakcija A postavlja S katanac nad R, a u trenutku t2transakcija B postavlja S katanac nad R. U trenutku t3 transakcija A ne mozeda postavi X katanac nad R i ide u stanje cekanja. U trenutku t4 transakcija Bne moze da postavi X katanac nad R i takode ide u stanje cekanja. Dakle, nijedna transakcija ne moze da nastavi rad i obe cekaju jedna na drugu, odnosnodolazi do mrtve petlje (engl. deadlock).

Page 53: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.2. KONKURENTNOST 53

Resenje problema zavisnosti od nepotvrdenih podataka

Vratimo se na primer transakcija A i B u primeru problema zavisnosti odnepotvrdenih podataka i pogledajmo koji se niz radnji izvrsava pod pret-postavkom dvofaznog protokola zakljucavanja.

T Transakcija A Transakcija B

... ... ...t1 —- UPDATE R (zahteva X nad R)t2 FETCH R (zahteva S nad R) —-t3 ceka ROLLBACK (tacka sinhronizacije, oslobada se X sa R)t4 FETCH R (ponovo se izvrsava i postavlja S nad R) —-

Tabela 3.7: Problem zavisnosti od nepotvrdenih podataka - resenje (slucaj a))

U trenutku t2 transakcija A je sprecena da procita nepotvrdene promene.Kada transakcija B uradi ROLLBACK oslobada se ekskluzivni katanac koji je onadrzala. Nakon toga, u trenutku t4, transakcija A ponovo pokusava da dobijedeljeni katanac nad R i ovog puta ga dobija.

Pogledajmo sada drugi scenario u kome transakcija A zeli da menja po-datke koje je druga transakcija vec izmenila, ali svoje izmene jos uvek nijepotvrdila.

T Transakcija A Transakcija B

... ... ...t1 —- UPDATE R (zahteva X nad R)t2 UPDATE R (zahteva X nad R) —-t3 ceka ROLLBACK (tacka sinhronizacije, oslobada se X sa R)t4 UPDATE R (ponovo se izvrsava i postavlja X nad R) —-

Tabela 3.8: Problem zavisnosti od nepotvrdenih podataka - resenje (slucaj b))

Pod pretpostavkom dvofaznog protokola zakljucavanja, u trenutku t2 transak-cija A bice sprecena da azurira nepotvrdene promene. Nakon sto transakcija Buradi ROLLBACK oslobada se ekskluzivni katanac nad R i transakcija A ponovopokusava da dobije ekskluzivni katanac nad R i ovaj put ga dobija.

Resenje problema nekonzistentne analize

Vratimo se na primer dve transakcije koje rade nad bankovnim racunima ipogledajmo sta se dobija koriscenjem mehanizma katanaca.

Koriscenjem mehanizma katanaca nekonzistentna analiza je sprecena, alise u trenutku t8 javila mrtva petlja.

Mrtva petlja

Kod problema izgubljenih azuriranja i nekonzistentne analize, resavanje sa-mog problema dovelo je do novog problema – uzajamnog blokiranja transak-cija. Mrtva petlja je situacija kada dve ili vise transakcija imaju postavljenkatanac nad resursom koji je potreban drugoj transakciji tako da nijedna tran-sakcija ne moze da nastavi sa radom. Mrtva petlja se otkriva koriscenjem

Page 54: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

54 GLAVA 3. TRANSAKCIJE

T Transakcija A Transakcija B

... ... ...t1 FETCH Rac1 (40), sum=40 (postavlja S na Rac1) —-t2 FETCH Rac2 (50), sum=90 (postavlja S na Rac2) —-t3 —- FETCH Rac3 (30) (postavlja S na Rac3)t4 —- UPDATE Rac3 (30→20) (postavlja X na Rac3)t5 —- FETCH Rac1 (40) (postavlja S na Rac1)t6 —- UPDATE Rac1 (40→50) (zahteva X na Rac1)t7 —- cekat8 FETCH Rac3 (20) (zahteva S na Rac3) cekat9 ceka ceka

Tabela 3.9: Problem nekonzistentne analize - resenje

grafa cekanja. To je usmereni graf koji ima po jedan cvor za svaku transak-ciju, dok grana (Ti, Tj) oznacava da transakcija Tj drzi katanac nad resursomkoje je potreban transakciji Ti, te transakcija Ti ceka da transakcija Tj oslo-bodi katanac na tom resursu. U ovako zadatom grafu mrtva petlja odgovarausmerenom ciklusu u grafu. Primer grafa cekanja dat je na slici 3.1.

Slika 3.1: Primer grafa cekanja u slucaju da transakcija T1 ceka na transakcijuT2, transakcija T2 na transakciju T3, a transakcija T3 na transakciju T1

Ideja je da se problem uzajamnog blokiranja transakcija ne sprecava, vecje potrebno detektovati mrtve petlje. Nakon toga se neka od transakcija kojaucestvuje u mrtvoj petlji bira za “zrtvu”, njeni efekti se ponistavaju i na tajnacin se oslobadaju svi katanci koje je ona drzala.

Zakljucavanje sa namerom

Prilikom zakljucavanja reda tabele, tabela koja sadrzi taj red se takode za-kljucava. Ovo zakljucavanje sa namerom ukazuje na plan koji transakcija ima upristupu podataka. U ovom slucaju, katanac na tabelu je jednog od narednihtipova: IS (intent share), IX (intent exclusive), SIX (share with intent exclu-sive). Ideja je da se konflikt izmedu zahteva otkrije vec na nivou tabele, prenego na nivou pojedinacnih redova tabele.

Tipovi katanaca i njihovi efekti su izlistani u rastucem redosledu kontrolenad resursima.

• IS katanac: transakcija koja ima katanac namerava da postavi S katanacnad pojedinacnim n-torkama tabele, radi garantovanja stabilnosti tih n-torki koje namerava da obraduje.

• IX katanac: isto kao i IS, plus sto transakcija koja ima katanac moze daazurira pojedinacne n-torke i tada postavlja X katanac na njih.

Page 55: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.3. OSOBINE TRANSAKCIJA I NIVOI IZOLOVANOSTI TRANSAKCIJA 55

Transakcija AX SIX IX S IS -

Transakcija B

X N N N N N YSIX N N N N Y YIX N N Y N Y YS N N N Y Y YIS N Y Y Y Y Y- Y Y Y Y Y Y

Tabela 3.10: Matrica kompatibilnosti nacina zakljucavanja.

• S katanac: transakcija tolerise konkurentno citanje ali ne i konkurentnoazuriranje. Transakcija nema nameru da azurira bilo koju n-torku iztabele.

• SIX katanac: ovo je kombinacija S i IX katanca, odnosno transakcijamoze da tolerise konkurentno citanje, ali transakcija namerava da azurirapojedinacne n-torke u kojem ce slucaju postaviti X katanac na te n-torke.

• X katanac: transakcija ne tolerise bilo kakav konkurentan pristup tabeli.Samo ona moze ali i ne mora da azurira n-torke ove tabele.

3.3 Osobine transakcija i nivoi izolovanosti transakcija

Jedan aplikativni program moze se sastojati od veceg broja transakcija. Op-eracije COMMIT i ROLLBACK zavrsavaju transakciju, ali ne prekidaju izvrsavanjeprograma.

Slika 3.2: Ilustracija programa koji se sastoji od tri transakcije

Izvrsavanje jedne transakcije moze da se zavrsi planirano ili neplanirano. Doplaniranog zavrsetka dolazi izvrsavanjem operacije COMMIT kojom se transak-cija uspesno zavrsava, ili eksplicitne ROLLBACK operacije, koja se izvrsava kadadode do greske za koju postoji programska provera (tada se radnje transak-cije ponistavaju, a program nastavlja sa radom izvrsavanjem sledece transak-cije). Neplanirani zavrsetak izvrsenja transakcije dogada se kada dode dogreske za koju ne postoji programska provera; tada se izvrsava implicitna

Page 56: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

56 GLAVA 3. TRANSAKCIJE

(sistemska) ROLLBACK operacija, radnje transakcije se ponistavaju a programprekida sa radom. I operacija COMMIT se moze implicitno izvrsiti, pri normal-nom zavrsetku programa, a takode i operacija BEGIN TRANSACTION, prilikominicijalizacije programa.

Izvrsavanjem operacije COMMIT, efekti svih azuriranja te transakcije postajutrajni, tj. vise se ne mogu ponistiti procedurom oporavka. U log datotekuse upisuje odgovarajuci slog o kompletiranju transakcije (COMMIT slog), a svikatanci koje je transakcija drzala nad objektima se oslobadaju. Izvrsenje COMMIToperacije ne podrazumeva nuzno fizicki upis svih azuriranih podataka u bazu(neki od njih mogu biti u baferu podataka, pri cemu se, efikasnosti radi, safizickim upisom u bazu ceka dok se baferi ne napune). Cinjenica da efektiazuriranja postaju trajni znaci da se moze garantovati da ce se upis u bazudogoditi u nekom narednom trenutku.

Pad transakcije nastaje kada transakcija ne zavrsi svoje izvrsenje plani-rano. Tada sistem izvrsava implicitnu – prinudnu ROLLBACK operaciju, tj. spro-vodi aktivnost oporavka od pada transakcije.

Pojedinacne radnje azuriranja u okviru jedne transakcije, kao i operacijapocetka transakcije (eksplicitna ili implicitna BEGIN TRANSACTION operacija),izvrsavaju se na nacin koji omogucuje oporavak baze u slucaju pada transak-cije. Oporavak podataka u bazi i vracanje baze u konzistentno stanje omogu-cuje se upisom svih informacija o ovim radnjama i operacijama u sistemskilog. Pri izvrsavanju operacija azuriranja (u uzem smislu), osim sto se azurirabaza, u log datoteci se beleze vrednosti svakog azuriranog objekta pre i posleazuriranja.

Izvrsavanjem operacije BEGIN TRANSACTION (bilo da je eksplicitna ili im-plicitna) u log datoteku se upisuje slog pocetka transakcije.

Operacija ROLLBACK, bilo eksplicitna ili implicitna, sastoji se od ponistavanjaucinjenih promena nad bazom. Izvrsava se citanjem unazad svih slogova izlog datoteke koji pripadaju toj transakciji, do BEGIN TRANSACTION sloga. Zasvaki slog, promena se ponistava primenom odgovarajuce UNDO-operacije.

ACID osobine transakcije

Transakcija se karakterise sledecim vaznim svojstvima (poznatim kao ACIDsvojstva):

• atomicnost (engl. Atomicity): transakcija se izvrsava u celosti ili se neizrsava ni jedna njena radnja;

• konzistentnost (engl. Consistency): transakcija prevodi jedno konzistentnostanje baze u drugo konzistentno stanje;

• izolacija (engl. Isolation): efekti izvrsenja jedne transakcije su nepoznatidrugim transakcijama sve dok ona ne zavrsi uspesno svoj rad;

• trajnost (engl. Durability): svi efekti uspesno zavrsene transakcije sutrajni, tj. mogu se ponistiti samo drugom transakcijom. Dakle, nakonpotvrde transakcije, promene ostaju u bazi, cak i u slucaju pada sistema.

Page 57: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.3. OSOBINE TRANSAKCIJA I NIVOI IZOLOVANOSTI TRANSAKCIJA 57

Nivoi izolovanosti

Zbog povecanja konkurentnosti, svojstvo izolovanosti transakcije (I u ACID)realizuje se u nekoliko nivoa koji se medu sobom razlikuju po stepenu u komeoperacije jedne transakcije mogu da uticu na izvrsenje operacija konkurentnihtransakcija, odnosno stepen u kome operacije drugih konkurentnih transak-cija mogu da uticu na izvrsavanje operacija posmatrane transakcije. Odnosno,na ovaj nacin se opisuje stepen ometanja koji tekuca transakcija moze da pod-nese pri konkurentnom izvrsavanju. Ove nivoe nazivamo nivoima izolo-vanosti transakcije (tj. celokupne aplikacije). Ako su transakcije serijaliz-abilne stepen ometanja ne postoji, tj. nivo izolovanosti je maksimalan. Realnisistemi iz razlicitih razloga (npr. iz razloga povecanja performansi) dopustajurad sa nivoima izolovanosti koji su manji od maksimalnog. Vazi da sto je vecinivo izolovanosti manje su dopustene smetnje i obratno.

SQL standard definise naredne nivoe izolovanosti (koji su navedeni u re-dosledu od najjaceg do najslabijeg):

• SERIALIZABLE

• REPEATABLE READ

• READ COMMITED

• READ UNCOMMITED

Prvi nivo izolovanosti SERIALIZABLE je najvisi nivo izolovanosti i garan-tuje serijalizabilnost izvrsenja. Standard definise i tri nacina na koja serijaliz-abilnost moze da bude narusena, ukoliko se ne radi sa najvisim nivoom izolo-vanosti i to su:

• prljavo citanje (engl. dirty read), odgovara pojmu zavisnosti od nepo-tvrdenih podataka. Na primer, transakcija A azurira neki slog, nakontoga transakcija B cita taj slog, a zatim transakcija A ponisti promene.Ono sto se desilo jeste da je transakcija B procitala slog koji ne postoji.

Primer:

1. transakcija A zapocinje sa radom

2. transakcija A: UPDATE Knjiga SET god izdavanja = 1990 WHERE

k sifra=123;

3. transakcija B zapocinje sa radom

4. transakcija B: SELECT * FROM Knjiga;

5. transakcija A: ROLLBACK;

Efekat ovog niza radnji jeste da transakcija B vidi podatke koje je izme-nila transakcija A, ali ove izmene jos uvek nisu potvrdene.

• neponovljivo citanje (engl. nonrepeatable read). Recimo transakcija Acita slog, zatim transakcija B azurira taj slog i posle toga transakcija Aponovo pokusava da procita “isti” slog.

Primer:

Page 58: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

58 GLAVA 3. TRANSAKCIJE

1. transakcija A zapocinje sa radom

2. transakcija A: SELECT * FROM Knjiga WHERE k sifra = 123;

3. transakcija B zapocinje sa radom

4. transakcija B: UPDATE Knjiga SET god izdavanja = 1990 WHERE

k sifra = 123;

5. transakcija B: COMMIT;

6. transakcija A: SELECT * FROM Knjiga WHERE k sifra = 123;

7. transakcija A: COMMIT;

Efekat ovog niza radnji jeste da transakcija A ponovnim citanjem istihpodataka dobija drugaciji rezultat.

• fantomsko citanje (engl. phantom read). Neka transakcija A cita skupslogova koji zadovoljavaju neki uslov, a zatim transakcija B unese novislog koji zadovoljava isti uslov. Ako transakcija A sada ponovi zahtev,tj. procita ponovo podatke po istom uslovu, videce slog koji ranije nijepostojao - tzv. fantomski slog.

Page 59: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.3. OSOBINE TRANSAKCIJA I NIVOI IZOLOVANOSTI TRANSAKCIJA 59

Primer:

1. transakcija A zapocinje sa radom

2. transakcija A: SELECT * FROM Knjiga WHERE god izdavanja > 1990;

3. transakcija B zapocinje sa radom

4. transakcija B: INSERT INTO Knjiga (124, ’Na Drini cuprija’,

’Prosveta’, 2000);

5. transakcija B: COMMIT;

6. transakcija A: SELECT * FROM Knjiga WHERE god izdavanja > 1990;

7. transakcija A: COMMIT;

Efekat ovog niza radnji jeste da transakcija B umece novi red koji zado-voljava uslov upita kojim transakcija A cita podatke i pri ponovnomcitanju dobijaju se novi redovi u rezultatu koji prethodno nisu postojali.

U tabeli 3.11 za svaki nivo izolovanosti prikazano je koji se od nabrojanihproblema mogu desiti.

Nivo izolovanosti Prljavo citanje Neponovljivo citanje Fantomsko citanjeSERIALIZABLE N N N

REPEATABLE READ N N YREAD COMMITED N Y Y

READ UNCOMMITED Y Y Y

Tabela 3.11: Moguci problemi koji se mogu javiti pri radu sa odredenimnivoom izolovanosti.

U sistemu DB2 postoje naredni nivoi izolovanosti (koji su navedeni u re-dosledu od najjaceg do najslabijeg):

• REPEATABLE READ (RR)

• READ STABILITY (RS)

• CURSOR STABILITY (CS)

– CURRENTLY COMMITED (CC)

• UNCOMMITED READ (UR)

Oni odgovaraju nivooima izolovanosti definisanim SQL standardom, ali sudrugacije imenovani.

Najvisi nivo izolovanosti aplikacije (i njenih transakcija) u sistemu DB2 jenivo ponovljivog citanja – RR (engl. repeatable read). Ovaj nivo obezbedujezakljucavanje svih vrsta kojima se transakcija obraca (npr. cele tabele), a nesamo onih vrsta koje zadovoljavaju uslov upita. Tako se rezultat citanja transak-cijom T ne moze promeniti od strane druge transakcije pre nego sto se transak-cija T zavrsi. Na primer, ako transakcija T sa nivoom izolovanosti RR zeli daprocita knjige izdate nakon 1990. godine naredbom SELECT * FROM Knjiga

WHERE god izdavanja>1990, ona zakljucava sve redove tabele Knjiga (a ne

Page 60: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

60 GLAVA 3. TRANSAKCIJE

samo one koji zadovoljavaju uslov upita). Katanci za citanje reda se drzedo naredne naredbe COMMIT ili ROLLBACK. S druge strane, ovaj nivo izolo-vanosti obezbeduje i da transakcija nema uvid u nepotvrdene promene drugihtransakcija.

Sledeci nivo izolovanosti jeste nivo stabilnosti citanja – RS (engl. readstability). Za razliku od prethodnog, ovaj nivo izolovanosti obezbeduje za-kljucavanje samo onih vrsta koje zadovoljavaju uslov upita, tj. ne dopusta pro-menu (od strane drugih transakcija) vrste koju je procitala transakcija T, svedo zavrsetka transakcije T. Mada ce, pri ovom nivou izolovanosti, vrsta kojuje procitala transakcija T ostati nepromenjena od strane drugih transakcijasve do zavrsetka transakcije T, rezultati ponovljenih izvrsenja istog upita odstrane transakcije T mogu da se razlikuju (moze da dode do dodavanja, odstrane drugih transakcija, vrsta koje ce zadovoljiti taj upit, tj. do efekta fan-tomskih redova). Na primer, ako transakcija T sa nivoom izolovanosti RSzeli da procita knjige izdate nakon 1990. godine naredbom SELECT * FROM

Knjiga WHERE god izdavanja>1990, ona zakljucava samo one koji zadovol-javaju uslov upita, te druga transakcija moze u meduvremenu dodati noveredove u tabelu Knjiga koji zadovoljavaju ovaj uslov i na taj nacin moze docido efekta fantomskog citanja, ako transakcija T ponovo procita redove tabeleKnjiga po istom uslovu. Katanci za citanje reda se drze do naredne naredbeCOMMIT ili ROLLBACK.

Nivo stabilnosti kursora – CS (engl. cursor stability) obezbeduje zakljuca-vanje samo one vrste koju transakcija T trenutno cita. Sve vrste koje je transak-cija T prethodno procitala (ali ne i menjala) otkljucane su i mogu ih drugetransakcije menjati i pre okoncanja transakcije T. Na primer, ako transakcijaT sa nivoom izolovanosti CS zeli da procita knjige izdate nakon 1990. go-dine odovarajucim kursorom, ona zakljucava samo aktivni red kursora, alise prelaskom na naredni red ovaj red otkljucava. Rad sa ovim nivoom izolo-vanosti moze dovesti do efekta fantomskog citanja, kao i neponovljivog citanjajer neka druga transakcija moze azurirati neki slog koji je transakcija T ranijeprocitala (i nakon toga pustila katanac na tom slogu), te se prilikom ponovnogzahteva transakcije T za citanjem istih podataka moze dobiti drugaciji rezul-tat. Transakcija T sa ovim nivoom izolovanosti i dalje nema uvid u promenedrugih transakcija pre okoncanja tih transakcija.

Nivo trenutno potvrdenih izmena – CC (engl. currently commited) jeuveden u verziji 9.7 i transakcijama sa ovim nivoom izolovanosti se citajusamo potvrdeni podaci. Na primer, ako je transakcija T menjala neki po-datak, a neka druga transakcija zeli da te podatke cita, ona ne mora da cekada transakcija T oslobodi katanac na tom redu. Umesto toga, ona moze da citapodatke, ali se vracaju vrednosti koje se zasnivaju na trenutno potvrdenim iz-menama, tj. podaci koji su bili pre pocetka operacije azuriranja transakcijomT. Ovaj nivo izolovanosti je podrazumevani nivo izolovanosti transakcija usistemu DB2 pocev od verzije 9.7, a do te verzije podrazumevani nivo izolo-vanosti bio je CS.

Najslabiji nivo izolovanosti transakcija jeste nivo nepotvrdenog citanja –UR (engl. uncommitted read). Transakcija T sa ovim nivoom izolovanosticita podatke bez toga da zahteva (i dobije) deljivi katanac na tom objektu.Usled prethodnog, ovaj nivo omogucuje transakciji T da procita nepotvrdenepromene drugih transakcija, kao i drugim transakcijama da pristupe podacimakoje transakcija T upravo cita.

Page 61: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.3. OSOBINE TRANSAKCIJA I NIVOI IZOLOVANOSTI TRANSAKCIJA 61

X katanci se ne oslobadaju sve do naredbe COMMIT ili ROLLBACK, bez obzirana nivo izolovanosti transakcije.

Izabrani nivo izolovanosti je vazeci tokom date jedinice posla. Za nekunaredbu SQL-a, nivo izolovanosti se utvrduje na sledeci nacin:

• za staticki SQL

– ako je za samu tu naredbu eksplicitno postavljen nivo izolovanosti,koristi se ta vrednost,

– ako za tu naredbu nije eksplicitno postavljen nivo izolovanosti, ko-risti se nivo izolovanosti koji je zadat prilikom ugradnje paketa ubazu

• za dinamicki SQL

– ako je za samu tu naredbu eksplicitno postavljen nivo izolovanosti,koristi se ta vrednost,

– ako za tu naredbu nije eksplicitno postavljen nivo izolovanosti i akoje naredbom SET CURRENT ISOLATION postavljena vrednost nivoaizolovanosti u tekucoj sesiji, koristi se ta vrednost,

– ako za naredbu nije postavljen nivo izolovanosti, niti je naredbomSET CURRENT ISOLATION postavljena vrednost nivoa izolovanostiza tekucu sesiju, koristi se nivo izolovanosti koji je zadat prilikomugradnje paketa u bazu.

Nivo izolovanosti za pojedinacnu naredbu se postavlja navodenjem stavkeWITH <nivo izolovanosti> nakon teksta naredbe, pri cemu <nivo izolovanosti>

ima jednu od vrednosti RR, RS, CS, UR. Ovo je moguce uraditi samo za nekenaredbe kao sto su recimo DECLARE CURSOR, INSERT, SELECT, SELECT INTO,itd.

Nivo izolovanosti se moze postaviti prilikom ugradnje paketa na sledecinacin:

BIND <paket> ISOLATION (RR|RS|CS|UR)

Za dinamicke SQL naredbe unutar jedne sesije moguce je postaviti nivoizolovanosti naredbom:

SET CURRENT ISOLATION = {RR|RS|CS|UR}

U okviru DB2 CLI pristupa, nivo izolovanosti transakcije se moze izmenitikoriscenjem funkcije SQLSetConnectAttr sa atributom SQL ATTR TXN ISOLATION

primenom na argument tipa ConnectionHandle. Atribut SQL ATTR TXN ISOLATION

treba postaviti na jednu od vrednosti:

• SQL TXN SERIALIZABLE,

• SQL TXN REPEATABLE READ,

• SQL TXN READ COMMITTED (podrazumevani),

• SQL TXN READ UNCOMMITTED.

Page 62: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

62 GLAVA 3. TRANSAKCIJE

U JDBC-u je moguce postaviti nivo izolovanosti transakcije pozivom metodasetTransactionIsolation(isolation) na objekat konekcije. Vrednost kojase prosleduje je jedna od gore navedenih vrednosti za nivo izolovanosti. Pritom,kada se kreira konekcija u JDBC-u, ona se nalazi u modu auto-commit, odnosnosvaka pojedinacna SQL naredba se razmatra kao transakcija i automatski sevrsi operacija COMMIT. Stoga je pre postavljanja nivoa izolovanosti potrebnonajpre pozvati setAutoCommit(false) na objekat konekcije.

Na CLP (Command Line Processor) konekciji moguce je iskoristiti naredbuCHANGE ISOLATION TO (RR|RS|CS|UR).

3.4 Oporavak1

Oporavak podrazumeva aktivnost koju sistem preduzima u slucaju da se,u toku izvrsenja jedne ili vise transakcija, otkrije neki razlog koji onemogucavanjihov uspesan zavrsetak. Taj razlog moze biti:

• u samoj transakciji, kao sto je prekoracenje neke od dozvoljenih vred-nosti (pad transakcije),

• u sistemu, npr. prestanak elektricnog napajanja (pad sistema), ili

• u disku na kome je baza podataka (pad medijuma).

Kako je transakcija logicka jedinica posla, njene radnje moraju ili sve uspe-sno da se izvrse ili nijedna, pa je u slucaju nemogucnosti uspesnog zavrsetkaneophodno ponistiti efekte parcijalno izvrsenih transakcija. Sa druge strane,moze se dogoditi da u trenutku pada sistema neki efekti uspesno komple-tiranih transakcija jos nisu upisani u bazu (npr. azurirani slogovi su jos uunutrasnjoj memoriji u baferu podataka ciji se sadrzaj pri padu sistema gubi);zato moze postojati potreba za ponovnim (delimicnim) izvrsenjem nekih pret-hodno uspesno kompletiranih transakcija. To ponistavanje odnosno ponovnoizvrsavanje u cilju uspostavljanja konzistentnog stanja baze predstavlja sis-temsku aktivnost oporavka od pada transakcije ili sistema.

U slucaju pada medijuma, oporavak ukljucuje pre svega prepisivanje arhivi-rane kopije baze na ispravan medijum, a zatim, eventualno, ponovno izvrsenjetransakcija kompletiranih posle poslednjeg arhiviranja a pre pada medijuma.

Ovako koncipiran oporavak nuzno se zasniva na postojanju ponovljenih(dupliranih) podataka i informacija na razlicitim mestima ili medijumima,tj. na mogucnosti rekonstrukcije informacije na osnovu druge informacije,ponovljeno smestene na drugom mestu u sistemu. Kao “drugo” mesto u sis-temu, na koje se (osim u bazu) upisuju informacije o izvrsenim radnjama,obicno se koristi tzv. log datoteka ili sistemski log.

Naredbom GET DATABASE CONFIGURATION mozemo dobiti informacije olokaciji log datoteke na sistemu, kao i o njenoj maksimalnoj velicini.

Komponenta SUBP odgovorna za oporavak baze podataka od pada transak-cije, sistema ili medijuma je upravljac oporavka. Njegova aktivnost se sastojiiz sledeceg niza radnji:

1Materijal iz ovog poglavlja je preuzet iz knjige prof. Gordane Pavlovic Lazetic: Baze po-dataka

Page 63: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.4. OPORAVAK 63

• periodicno prepisuje (engl. dump) celu bazu podataka na medijum zaarhiviranje;

• pri svakoj promeni baze podataka, upisuje slog promene u log datoteku,sa tipom promene i sa novom i starom vrednoscu pri azuriranju, sanovom vrednoscu pri unosenju u bazu, odnosno starom vrednoscu pribrisanju iz baze;

• u slucaju pada transakcije ili sistema, stanje baze podataka moze bitinekonzistentno; upravljac oporavka koristi informacije iz log datotekeda ponisti dejstva parcijalno izvrsenih transakcija odnosno da ponovoizvrsi neke kompletirane transakcije; arhivirana kopija baze podatakase ne koristi;

• u slucaju pada medijuma (npr. diska na kome je baza podataka), “na-jsvezija” arhivirana kopija baze podataka se prepisuje na ispravni medi-jum (disk), a zatim se koriste informacije iz log datoteke za ponovnoizvrsenje transakcija kompletiranih posle poslednjeg arhiviranja a prepada medijuma.

Da bi se omogucilo upravljacu oporavka da ponisti odnosno da ponovoizvrsi transakcije, potrebno je obezbediti procedure kojima se ponistavaju od-nosno ponovo izvrsavaju pojedinacne radnje tih transakcija kojima se menjabaza podataka. Baza podataka menja se operacijama azuriranja, unosenjaili brisanja podataka, pa pored procedura za izvrsenje tih operacija, SUBPmora biti snabdeven i odgovarajucim procedurama za ponistavanje odnosnoponovno izvrsavanje tih operacija, na osnovu starih odnosno novih vrednostizapamcenih u log datoteci. Drugim recima, SUBP poseduje, osim tzv. DO-logike (“uradi”), i tzv. UNDO (“ponisti”) i REDO (“ponovo uradi”) logiku.

Pad sistema ili medijuma moze se dogoditi i u fazi oporavka od prethodnogpada. Zato moze doci do ponovnog ponistavanja vec ponistenih radnji, od-nosno do ponovnog izvrsavanja vec izvrsenih radnji. Ova mogucnost zahtevada UNDO i REDO logika imaju svojstvo idempotentnosti, tj. da je:

UNDO(UNDO(x)) ≡ UNDO(x)

REDO(REDO(x)) ≡ REDO(x)

za svaku radnju x. U log datoteci pokazivacima su povezani slogovi kojise odnose na jednu transakciju. Pretpostavlja se da log datoteka nikada, iliveoma retko, “pada”, tj. da je, zahvaljujuci sopstvenom dupliranju, tripli-ranju, itd na raznim medijumima, ona uvek dostupna.

Oporavak od pada transakcije

Kao sto smo vec pomenuli izvrsenje jedne transakcije moze da se zavrsi plani-rano ili neplanirano. Neplanirani zavrsetak izvrsenja transakcije dogada sekada dode do greske za koju ne postoji programska provera; tada se izvrsavaimplicitna (sistemska) ROLLBACK operacija, radnje transakcije se ponistavaju aprogram prekida sa radom.

Oporavak podataka u bazi i vracanje baze u konzistentno stanje omogucujese upisom svih informacija o ovim radnjama i operacijama u log datoteku.

Page 64: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

64 GLAVA 3. TRANSAKCIJE

Izvrsavanjem operacije BEGIN TRANSACTION (bilo da je eksplicitna ili implic-itna) u log datoteku se upisuje slog pocetka transakcije. Operacija ROLLBACK,bilo eksplicitna ili implicitna, sastoji se od ponistavanja ucinjenih promenanad bazom. Izvrsava se citanjem unazad svih slogova iz log datoteke koji pri-padaju toj transakciji, do BEGIN TRANSACTION sloga. Za svaki slog, promenase ponistava primenom odgovarajuce UNDO-operacije. Aktivnost oporavkaod pada transakcije ne ukljucuje REDO logiku.

Oporavak od pada sistema

U slucaju pada sistema, sadrzaj unutrasnje memorije je izgubljen. Zato se, poponovnom startovanju sistema, za oporavak koriste podaci iz log datoteke dabi se ponistili efekti transakcija koje su bile u toku u trenutku pada sistema.Ove transakcije se mogu identifikovati citanjem sistemskog loga unazad, kaotransakcije za koje postoji BEGIN TRANSACTION slog ali ne postoji COMMIT slog.

Da bi se smanjila kolicina posla potrebna za ponistavanje transakcija, uvodese, u pravilnim intervalima, obicno posle odredenog broja upisanih slogovau log datoteku, tzv. tacke pamcenja (engl. savepoint). U momentu kojiodreduje tacku pamcenja, fizicki se upisuju podaci i informacije iz log baferai bafera podataka (koji su u unutrasnjoj memoriji) u log datoteku i u bazupodataka, redom, i upisuje se slog tacke pamcenja u log datoteku. Ovaj slogsadrzi informaciju o svim aktivnim transakcijama u momentu tacke pamcenja,adrese poslednjih slogova tih transakcija u log datoteci, a moze sadrzati i nizdrugih informacija o stanju baze podataka u tom trenutku. Adresa sloga tackepamcenja upisuje se u datoteku ponovnog startovanja (engl. restart file).

Fizicki upis u tacki pamcenja znaci da ce se sadrzaj bafera prepisati naspoljni medijum bez obzira da li su baferi puni ili ne. To dalje znaci da sefizicki upis svih azuriranih podataka uspesno zavrsene transakcije moze garan-tovati tek u tacki pamcenja koja sledi za uspesnim zavrsetkom transakcije.Tako dolazimo do zakljucka da su zavrsetak transakcije (upis COMMIT slogau log datoteku) i definitivni upis svih azuriranja te transakcije u bazu – dveodvojene radnje, za koje se ne sme dogoditi da se jedna izvrsi a druga ne.Mehanizam koji to obezbeduje je protokol upisivanja u log unapred (engl.WAL – Write Ahead Log). Prema ovom protokolu, pri izvrsenju operacijeCOMMIT najpre se odgovarajuci slog fizicki upisuje u log datoteku, pa se zatimpodaci upisuju iz bafera podataka u bazu. Ako dode do pada sistema posleupisa COMMIT sloga u log datoteku a pre nego sto je sadrzaj bafera podatakaprepisan u bazu, taj se sadrzaj moze restaurisati iz sistemskog loga REDOlogikom.

Pri ponovnom startovanju sistema, posle pada sistema, moguce je premasadrzaju log datoteke identifikovati neuspele transakcije – kandidate za poni-stavanje, i uspele transakcije – kandidate za ponovno izvrsavanje. Oporavakbaze podataka tada se vrsi prema protokolu koji se moze opisati sledecimpseudokodom:

BEGIN

naci slog poslednje tacke pamcenja u log datoteci

(iz datoteke ponovnog startovanja);

IF u poslednjoj tacki pamcenja nema aktivnih transakcija

i slog tacke pamcenja je poslednji slog u log datoteci,

Page 65: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.4. OPORAVAK 65

oporavak je zavrsen

ELSE

BEGIN

formirati dve prazne liste transakcija: uspele i neuspele;

sve transakcije aktivne u poslednjoj tacki pamcenja

staviti u listu neuspelih;

citati redom log datoteku od tacke pamcenja do kraja:

kada se naidje na slog ‘‘pocetak transakcije’’,

dodati transakciju listi neuspelih;

kada se naidje na slog ‘‘kraj transakcije’’,

dodati (premestiti) tu transakciju u listu uspelih;

citati unazad log datoteku (od kraja)

i ponistiti akcije i efekte neuspelih transakcija;

citati log datoteku od poslednje tacke pamcenja unapred

i ponovo izvrsiti uspele transakcije

END

END.

Razmotrimo izvrsavanje skupa transakcija koje su prikazane na slici 3.3.Na vremenskoj osi oznacene su dve tacke: tpam – tacka pamcenja, i tpad –tacka pada sistema. Transakcija T1 zavrsila je rad pre poslednje tacke pamcenja,pa su njena azuriranja trajno upisana u bazu aktivnoscu postavljanja te tacke,i zato ona ne ulazi u proces oporavka. Transakcije T2 i T3 zavrsile su sa radomposle momenta tpam a pre pada sistema. U momentu pada sistema aktivnesu transakcije T4 i T5. Zbog toga prethodni protokol svrstava transakcije T4

i T5 u listu neuspelih (cija dejstva ponistava), a transakcije T2 i T3 u listu us-pelih (koje zatim ponovo izvrsava od tacke tpam). Time je zavrsena aktivnostoporavka od pada sistema.

Slika 3.3: Pad sistema pri izvrsavanju skupa instrukcija

Poboljsanja procedure oporavka

Postoji niz poboljsanja i modifikacija izlozenog postupka oporavka od padasistema. Tako je moguce sva upisivanja jedne transakcije u bazu ostaviti za

Page 66: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

66 GLAVA 3. TRANSAKCIJE

trenutak izvrsenja COMMIT operacije te transakcije, cime se eliminise potrebaza UNDO logikom.

Jedno evidentno poboljsanje protokola oporavka od pada sistema odnosise na aktivnosti vezane za tacku pamcenja. Naime, prethodno opisani pro-tokol ponistava efekte neuspelih transakcija koji mozda nisu ni bili ubelezeniu bazu (vec samo u bafer podataka ako su se dogodili posle tacke pamcenja),odnosno ponovo izvrsava radnje uspelih transakcija od tacke pamcenja, iakoje moguce da su efekti tih radnji, zbog popunjenosti bafera podataka, upisaniu bazu pre pada sistema.

Moguce je eliminisati fizicko upisivanje bafera podataka u bazu podatakau tacki pamcenja, a u fazi oporavka od pada sistema ponistavati samo oneradnje neuspelih transakcija ciji su efekti upisani u bazu, odnosno ponovoizvrsavati samo one radnje uspelih transakcija ciji efekti nisu upisani u bazu.U tom cilju uvodi se, u svaki slog log datoteke, u vreme njegovog upisa u log,jedinstvena oznaka, tzv. serijski broj u logu (engl. LSN – Log Sequence Num-ber). Serijski brojevi su u rastucem poretku. Osim toga, kadgod se azuriranastranica fizicki upisuje u bazu podataka, u stranicu se upisuje i LSN sloga logdatoteke koji odgovara tom azuriranju. U log datoteci moze biti vise slogovakoji odgovaraju azuriranju iste stranice baze podataka. Ako je serijski brojupisan u stranicu P veci ili jednak serijskom broju sloga log datoteke, efekatazuriranja kome odgovara taj slog fizicki je upisan u bazu; ako je manji, efekatnije upisan.

Da bi se slog iz baze podataka azurirao, potrebno je procitati (iz baze)stranicu na kojoj se slog nalazi. Posle azuriranja sloga, stranica je (u baferupodataka) spremna za upis u bazu, pri cemu i dalje nosi serijski broj svogprethodnog upisa u bazu.

Sada se u proceduru registrovanja tacke pamcenja, osim sto se eliminisefizicki upis bafera podataka u bazu, moze dodati upis, u slog tacke pamcenja,vrednosti LSN m najstarije stranice bafera podataka, tj. najmanjeg LSN stranicaiz bafera podataka, koje su azurirane ali jos nisu upisane u bazu.

Slog sistemskog loga sa serijskim brojem m odgovara tacki u sistemskomlogu od koje treba, umesto od tacke pamcenja, pri oporavku od pada sistemaponovo izvrsavati uspele transakcije. Kako tacka m prethodi tacki pamcenja,moze se desiti da neka transakcija koja je uspesno kompletirana pre tackepamcenja, “upadne” u skup aktivnih (uspelih) transakcija (transakcija T1 ,slika 3.4). Na takvu transakciju primenice se procedura oporavka, mada se tone bi dogodilo u prethodnoj varijanti oporavka; to je “cena” smanjenog brojaponistavanja, ponovnog izvrsavanja i fizickog upisa koje obezbeduje ovaj pos-tupak.

Procedura oporavka od pada sistema sada ima sledeci izgled:

BEGIN

formirati dve prazne liste transakcija: uspele i neuspele;

sve transakcije aktivne u tacki m staviti u listu neuspelih;

citati redom log datoteku od tacke m do kraja:

kada se naidje na slog ‘‘pocetak transakcije’’,

dodati transakciju listi neuspelih;

kada se naidje na slog ‘‘kraj transakcije’’,

dodati (premestiti) tu transakciju u listu uspelih;

citati unazad log datoteku (od kraja)

Page 67: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.4. OPORAVAK 67

i ponistiti efekte onih radnji neuspelih transakcija

za koje je p>=r, gde je r - LSN tekuceg sloga

a p - LSN odgovarajuce stranice baze podataka;

citati log datoteku od tacke m unapred

i ponovo izvrsiti one radnje uspelih transakcija

za koje je p < r (p, r - kao u prethodnom koraku)

END.

Slika 3.4: Oporavak od pada sistema koriscenjem serijskih brojeva

SQL podrska za tacke pamcenja

Tacka pamcenja predstavlja mehanizam za ponistavanje efekata nacinjenih odstrane SUBP-a u situaciji kada neki zahtev nad bazom podataka ne uspe. Akose javi greska tokom izvrsavanja, mehanizam tacaka pamcenja omogucavada se poniste izmene koje su se desile tokom trajanja transakcije od trenutkakada je tacka pamcenja pocela do trenutka u kom je zahtevano ponistavanjeefekata. Na ovaj nacin omoguceno je da se jedna velika transakcija podeli unekoliko delova tako da svaki od njih ima svoju definisanu tacku pamcenja.

Tacka pamcenja se pravi naredbom:

SAVEPOINT <naziv>

Radi povecanja jasnoce koda predlaze se da se tackama pamcenja daju infor-mativna imena. Dodatne opcije koje se mogu zadati prilikom pravljenja tackepamcenja su:

• UNIQUE - isti naziv tacke pamcenja se nece javiti ponovo sve dok je tackapamcenja aktivna,

• ON ROLLBACK RETAIN CURSORS - kad god je moguce kursori ce ostatineizmenjeni nakon operacije ROLLBACK TO SAVEPOINT,

• ON ROLLBACK RETAIN LOCKS - katanci koji su dobijeni nakon tacke pam-cenja se ne oslobadaju nakon operacije ROLLBACK TO SAVEPOINT.

Page 68: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

68 GLAVA 3. TRANSAKCIJE

Ukoliko neka tacka pamcenja vise nije potrebna, ona se moze osloboditi.Oslobadanje tacke pamcenja vrsi se naredbom:

RELEASE SAVEPOINT <naziv>

Ako se tacka pamcenja eksplicitno ne oslobodi, ona ce biti oslobodena na krajutransakcije.

Da bi se izvrsio povratak na neku tacku pamcenja potrebno je pozvatinaredbu:

ROLLBACK TO SAVEPOINT <naziv>

Ovom naredbom se sve izmene nad bazom podataka koje su vrsene nakon tetacke pamcenja ponistavaju. Ukoliko se ne navede naziv tacke pamcenja vrsise ROLLBACK na poslednju aktivnu tacku pamcenja. Sve tacke pamcenja kojesu postavljene nakon te tacke pamcenja se oslobadaju, dok se tacka pamcenjana koju je izvrsen ROLLLBACK ne oslobada.

Na primer, mozemo imati niz operacija oblika:

...

SAVEPOINT s1 ON ROLLBACK RETAIN CURSORS;

INSERT ...

INSERT ...

IF ...

ROLLBACK TO SAVEPOINT s1;

SAVEPOINT s2 ON ROLLBACK RETAIN CURSORS;

UPDATE ...

DELETE ...

COMMIT;

Ukoliko je tacka pamcenja vec oslobodena, nije moguce izvrsiti povratakna nju naredbom ROLLBACK TO SAVEPOINT.

U sistemu DB2 dozvoljeno je imati naredbe DDL-a unutar tacke pamcenja.Ako aplikacija uspesno oslobodi tacku pamcenja (naredbom RELEASE), onamoze da nastavi da koristi SQL objekte koji su kreirani naredbama DDL-aunutar te tacke pamcenja. Ipak, ako je aplikacija izvrsila naredbu ROLLBACK

TO SAVEPOINT za tacku pamcenja koja izvrsava naredbe DDL-a, DB2 oznacavaneispravnim sve kursore koji su zavisni od ovih naredbi.

Page 69: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.5. KATANCI I ZAKLJUCAVANJE – PROSIRENJE 69

3.5 Katanci i zakljucavanje – prosirenje

Svaki katanac karakterisu naredna svojstva:

• velicina – odreduje opseg, odnosno nivo katanca. Moguce vrednosti su:prostor tabela, tabela ili red (i jos particija ili stranica u z/OS),

• vrsta, mod – odreduje nacine pristupa koji su dozvoljeni vlasniku katanca,kao i nacine pristupa koji su dozvoljeni konkurentnim korisnicima za-kljucanog objekta,

• objekat – resurs koji se zakljucava; objekat koji se zakljucava takode pred-stavlja granularnost katanca,

• trajanje – vremenski interval tokom koga se katanac drzi, on zavisi odnivoa izolovanosti transakcije.

U katanac

Slika 3.5: Koriscenje U katanca

Koriscenje U (update) katanca onemogucava da dva poziva iste transakcijenaprave mrtvu petlju na istom redu. Namera da se menja onemogucava dadva poziva izvode operacije na istom redu u isto vreme, obzirom da su obapoziva kroz definiciju kursora naglasila mogucu zelju da dobiju X katanac.

U gornjem delu slike 3.5 terminal 1 trazi da otvori kursor i cita prvi red.On dobija IS katanac na tabeli i S katanac na redu. Terminal 2 trazi da otvorikursor i cita prvi red. Dobija IS katanac na tabeli i S katanac na istom redu.Terminal 1 pokusava da azurira procitani red. Dobija IX katanac na tabeli, alimu treba i X katanac na redu. On ne moze da dobije X katanac na redu zatosto terminal 2 drzi S katanac na redu. Stoga on ceka. Terminal 2 odlucujeda azurira red dok ga ceka. On dobija IX katanac na tabeli kroz konverzijukatanca. Medutim, da bi menjao zeljeni red, on mora da dobije X katanac natom redu, a ne moze da ga dobije jer terminal 1 na njemu drzi S katanac. Ovimdolazimo do mrtve petlje.

Page 70: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

70 GLAVA 3. TRANSAKCIJE

U donjem delu slike 3.5 prikazan je isti scenario u slucaju da se koristi Ukatanac. Terminal 1 otvara kursor i cita prvi red, on dobija IX katanac na tabeli,a U katanac na redu, nakon toga terminal 2 otvara kursor i, takode, zeli daprocita prvi red. On dobija IX katanac na tabeli, ali ceka na U katanac na redu.Terminal 1 azurira red koji cita i promovise svoj katanac u X katanac na redu.Terminal 2 ceka dok terminal 1 ne izvrsi COMMIT ili dok ne istekne maksimalnodozvoljeno vreme cekanja na katanac. Na ovaj nacin je dakle, dobijanje Ukatanaca ogranicilo stepen konkurentnosti transakcija, ali je i sprecilo pojavumrtve petlje.

Katanci na tabelama

DB2 uvek zahteva katanac na tabeli pre nego sto se dozvoli pristup podacima.DB2 moze takode da zahteva katanac na prostoru tabela, ali ova vrsta katancase u principu ne odnosi na programera aplikacije, te nece biti diskutovana unastavku teksta.

Slika 3.6: DB2 koristi ili striktno zakljucavanje tabele ili zakljucavanje tabelezajedno sa zakljucavanjem reda/stranice

DB2 moze da zakljuca samo tabelu (ovo se nekada naziva striktno zaklju-cavanje tabele) ili moze da zakljuca i tabelu i redove ili stranice tabele (slika3.6). Ukoliko strategija zakljucavanja ne ukljucuje zakljucavanje reda ili stran-ice, tabela se zakljucava u modu koji se odnosi na citavu tabelu, te ce celatabela biti zakljucana na isti nacin. Ukoliko strategija zakljucavanja ukljucujezakljucavanje redova ili stranica, tabela se zakljucava pre zakljucavanja za-htevanih redova, odnosno stranica. Tabela se u ovom pristupu zakljucava nanizem nivou restrikcije u odnosu na strategiju koja zakljucava samo tabelu.

Na slici 3.7 prikazane su neke vrste katanaca koje sistem DB2 koristi nanivou tabela:

• IN (intent none) – vlasnik katanca moze da cita sve podatke u tabeliukljucujuci i nepotvrdene podatke, ali ne moze da ih menja. Drugekonkurentne aplikacije mogu da citaju ili da azuriraju tabelu. Ne postavl-jaju se nikakvi katanci na redovima

• IS (intent share) – vlasnik katanca moze da cita proizvoljan podatak utabeli ako se S katanac moze dobiti na redovima ili stranicama od in-teresa

Page 71: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.5. KATANCI I ZAKLJUCAVANJE – PROSIRENJE 71

Slika 3.7: Modovi zakljucavanja tabela

• IX (intent exclusive) – vlasnik katanca moze da cita ili menja proizvoljnipodatak u tabeli ako se (a) X katanac moze dobiti na redovima ili strani-cama koje zelimo da menjamo i (b) S ili U katanac moze dobiti na re-dovima koje zelimo da citamo

• SIX (share with intention exclusive) – vlasnik katanca moze da cita svepodatke iz tabele i da menja redove ako moze da dobije X katanac natim redovima. Za citanje se ne dobijaju katanci na redovima. Drugekonkurentne aplikacije mogu da citaju iz tabele. SIX katanac se dobijaako aplikacija ima IX katanac na tabeli i onda se zahteva S katanac iliobratno.

• S (share) – vlasnik katanca moze da cita proizvoljan podatak u tabeli inece dobiti katance na redovima ili stranicama

• U (update) – vlasnik katanca moze da cita proizvoljan podatak u tabeli imoze da menja podatke ako se na tabeli moze dobiti X katanac. Pritomse ne dobijaju nikakvi katanci na redovima ili stranicama

• X (exclusive) – vlasnik katanca moze da cita i da menja proizvoljan po-datak iz tabele. Pritom se ne dobijaju nikakvi katanci na redovima ilistranicama

• Z (super exclusive) – ovaj katanac se zahteva na tabeli u posebnim pri-likama, kao sto su recimo menjanje strukture tabele ili njeno brisanje.Nijedna druga aplikacija (ni ona sa UR nivoom izolovanosti) ne mozeda cita niti da azurira podatke u tabeli.

Modovi IS i IX se koriste na nivou tabela da daju podrsku katancima naredovima ili stranicama. Oni omogucavaju zakljucavanje na nivou redova istranica i pritom sprecavaju jos neki ekskluzivni katanac na tabeli od stranedruge transakcije. Ako transakcija ima IS katanac na tabeli, ona moze da do-bije katanac na redu ili stranici samo za citanje; druga transakcija moze takodeda cita taj isti red ili stranicu, a moze, takode, i da menja podatak u nekom dru-gom redu tabele. Ako transakcija ima IX katanac, ona moze da dobije katanac

Page 72: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

72 GLAVA 3. TRANSAKCIJE

na redu/stranici za menjanje, a i druga transakcija moze da dobije katanac zacitanje ili menjanje na drugim redovima/stranicama tabele.

Modovi S, U i X se koriste na nivou tabela da nametnu striktnu strate-giju zakljucavanja tabela. Za transakcije koje koriste ovaj vid zakljucavanja nekoristi se nikakvo zakljucavanje na nivou redova ili stranica. Transakcija kojaima S katanac na tabeli moze da cita proizvoljan podatak iz tabele; na taj nacindruge transakcije mogu da dobiju katance koji podrzavaju zahteve samo zacitanjem nekog podatka iz tabele; nijedna druga transakcija ne moze da menjanijedan podatak iz tabele sve dok se S katanac ne oslobodi. Ako transakcijaima U katanac na tabeli ona moze da cita proizvoljan podatak iz tabele i even-tualno da menja podatke iz tabele tako sto dobija X katanac; druge transakcijemogu samo da citaju podatke iz tabele. Ako transakcija ima X katanac natabeli ona moze da cita i menja proizvoljan podatak iz tabele, a nijedna drugatransakcija ne moze da pristupi nijednom podatku iz tabele, niti za citanjeniti za menjanje (osim onih sa UR nivoom izolovanosti kada je moguce dapristupi izmenjenim redovima ili stranicama). Na slici 3.8 prikazana je tabelakompatibilnosti katanaca koje je moguce dobiti na tabeli.

Slika 3.8: Kompatibilnost katanaca koji se mogu dobiti na tabeli

Na slici 3.9 je prikazan stepen konkurentnosti koji je dozvoljen u razlicitimstrategijama zakljucavanja. Programi sa leve strane slike ne mogu konku-rentno da pristupe zeljenoj tabeli zbog globalne prirode katanca koji ima prviprogram. Striktni katanac na tabelu se moze zahtevati naredbom:

EXEC SQL LOCK TABLE <naziv_tabele> IN SHARE|EXCLUSIVE MODE;

Ako se u okviru naredbe navede kljucna rec SHARE trazi se S katanac, a ako senavede EXCLUSIVE trazi se X katanac.

Programi na desnoj strani iste slike konkurentno pristupaju ciljnoj tabeli.Strategije sa namerom (engl. intent) koje se koriste (koriscenjem IX i IS katanaca)dozvoljavaju ovakav vid konkurentnosti. U ovoj strategiji se svaki konflikt uzakljucavanju javlja na nivou reda ili stranice.

Page 73: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.5. KATANCI I ZAKLJUCAVANJE – PROSIRENJE 73

Slika 3.9: Zakljucavanje tabele vs. zakljucavanje redova/stranica

Efekti trazenja katanaca

U nekim situacijama katanci koji su potrebni da bi se izvrsila neka naredbajedne aplikacije su u konfliktu sa katancima koje vec imaju druge konkurentneaplikacije. Takmicenje medu aplikacijama za katance moze da izazove cekanjena katance, isticanje maksimalnog dozvoljenog cekanja na katanac, mrtve pet-lje i ekskalaciju katanaca.

Da bi se usluzio sto veci broj aplikacija, menadzer baza podataka omogu-cava funkciju ekskalacije katanaca. Ovaj proces objedinjuje proces dobijanjakatanca na tabeli, a oslobadanja katanaca na redovima. Zeljeni efekat je dase smanje ukupni zahtevi skladistenja za katance od strane menadzera bazapodataka. Ovo ce omoguciti drugim aplikacijama da dobiju zeljene katance.

Dva konfiguraciona parametra baze podataka imaju direktan uticaj na pro-ces ekskalacije katanaca:

• locklist: to je prostor u globalnoj memoriji baze podataka koji se ko-risti za skladistenje katanaca,

• maxlocks: to je procenat ukupne liste katanaca koji je dozvoljeno da drzijedna aplikacija.

Oba parametra su konfigurabilna.Ekskalacija katanaca se desava u dva slucaja:

• aplikacija zahteva katanac koji bi proizveo da ona prevazide procenatukupne velicine liste katanaca, koji je definisan parametrom maxlocks.U ovoj situaciji menadzer baze podataka ce pokusati da oslobodi mem-orijski prostor dobijanjem jednog katanca na tabelu, a oslobadanjem ka-tanaca na redove.

• aplikacija ne moze da dobije katanac jer je lista katanaca puna. Menadzerbaze podataka ce pokusati da oslobodi memorijski prostor tako sto ce

Page 74: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

74 GLAVA 3. TRANSAKCIJE

dobiti katanac na tabelu, a osloboditi katance na redove. Primetimo daaplikacija koja pokrece ekskalaciju katanaca moze ali i ne mora da imaznacajan broj katanaca.

Ekskalacija katanaca moze da ne uspe. Ako se desi greska, aplikacija kojaje pokrenula ekskalaciju dobice vrednost SQLCODE -912. Ovaj kod bi trebaloda bude obraden od strane aplikacije.

Detekcija prekoracenog vremena cekanja na katanac (engl. lock time-out) je svojstvo menadzera baza podataka kojim se sprecava da aplikacijabeskonacno dugo ceka na katanac.

Na primer, transakcija moze da ceka na katanac koji drzi aplikacija drugogkorisnika, ali drugi korisnik je napustio radno mesto bez toga da je omogucioaplikaciji da uspesno zavrsi svoj posao, cime bi se oslobodio katanac. Dabi se izbegao zastoj aplikacije u ovom slucaju, moze se postaviti konfigu-racioni parametar locktimeout na maksimalno vreme koje proizvoljna ap-likacija moze da ceka da bi dobila katanac. Postavljanje ovog parametra po-maze da se izbegnu globalne mrtve petlje. Na primer, ako aplikacija 1 pokusada dobije katanac koji vec drzi aplikacija 2, aplikacija 1 dobija SQLCODE -911

(SQLSTATE 40001) with reason code 68 ako je prekoraceno vreme cekanjana katanac. Podrazumevana vrednost parametra locktimeout je -1 sto oznacavada je ova opcija iskljucena.

Mrtva petlja se obraduje procesom u pozadini koji se naziva detektor mrtvepetlje. Ako se uoci mrtva petlja, odreduje se “zrtva”, zatim se za nju au-tomatski poziva ROLLBACK i vraca se SQLCODE -911 with reason code 2. Po-nistavanje radnji zrtve oslobada katanace i to bi trebalo da omoguci drugimprocesima da nastave sa radom.

Parametar dlchktime definise frekvenciju sa kojom se proverava da li jedoslo do mrtve petlje izmedu aplikacija koje su povezane na bazu podataka.Ovaj parametar je konfigurabilan i vrednost mu je izrazena u milisekundama.Ako je ova vrednost postavljena na neku veliku vrednost, onda se povecavavreme koje ce aplikacije cekati dok se ne otkrije mrtva petlja, ali se stedi cenaizvrsavanja detektora mrtve petlje. S druge strane, ako se ova vrednost postavina neku malu vrednost, onda ce se mrtve petlje brzo otkrivati, ali ukupneperformanse mogu biti smanjene jer se cesto rade provere. Podrazumevanavrednost ovog parametra je 10s.

Vrednosti svih ovih parametara (i mnogih drugih) mogu se procitati nared-bom:

GET DATABASE CONFIGURATION FOR <naziv_baze_podataka>

Vrednost nekog parametra moguce je izmeniti naredbom:

UPDATE DATABASE CONFIGURATION FOR <naziv_baze_podataka>

<parametar> <vrednost>

Na primer, vrednost parametra locktimeout moguce je izmeniti za bazu po-dataka BPKnjiga na sledeci nacin:

UPDATE DATABASE CONFIGURATION FOR BPKnjiga LOCKTIMEOUT 30

Page 75: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

3.5. KATANCI I ZAKLJUCAVANJE – PROSIRENJE 75

Kursori deklarisani sa opcijom WITH HOLD

U principu, izvrsavanjem naredbi za kraj transakcije (COMMIT i ROLLBACK) zat-varaju se otvoreni kursori i oslobadaju katanci. Obzirom da je nekada zgodnoda nakon uspesnog kraja transakcije otvoreni kursor i dalje ostane otvoren,moguce je deklarisati kursor koriscenjem opcije WITH HOLD cime on ostajeotvoren i nakon uspesnog kraja transakcije.

Kursori mogu biti deklarisani koriscenjem opcije WITH HOLD na sledeci nacin:

DECLARE <naziv> CURSOR WITH HOLD FOR

<upit>

Na ovaj nacin kursor ostaje otvoren sve dok se eksplicitno ne zatvori, ilise ne izvrsi naredba ROLLBACK. Prilikom izvrsavanja naredbe COMMIT, otvorenikursori koji su deklarisani sa opcijom WITH HOLD ostaju otvoreni i pridruzenikatanci na tabelama se zadrzavaju. Na ovaj nacin nakon izvrsavanja naredbeCOMMIT naredni red u rezultatu se moze procitati naredbom FETCH.

Dakle, izvrsavanje naredbe COMMIT:

• zatvara sve kursore koji nisu definisani sa opcijom WITH HOLD,

• oslobada sve katance osim na tekucem redu kursora koji su definisanisa opcijom WITH HOLD,

• transakcija se potvrduje i sve promene se trajno zapisuju u bazi po-dataka u smislu da postaju dostupne svim konkurentnim ili narednimtransakcijama.

Izvrsavanje naredbe ROLLBACK:

• zatvara sve kursore,

• oslobada sve katance,

• ponistava sve promene nastale tokom transakcije.

Page 76: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se
Page 77: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Glava 4

Objektno-relaciono preslikavanje ialat Hibernate

U okviru ovog poglavlja bice prikazan koncept objektno-relacionog pres-likavanja (engl. Object Relation Mapping - ORM) kao i alat Hibernate kojise koristi za objektno-relaciono preslikavanje. Objektno-relacionim preslika-vanjem se definise prevodenje elemenata objektnog modela u elemente rela-cionog modela i obrnuto. Cilj objektno-relacionog preslikavanja je automati-zacija prenosa i konvertovanja podataka, kao i struktura podataka.

Prilikom dizajniranja aplikacija koje koriste baze podataka za skladistenjepodataka, potrebno je obezbediti mogucnost preuzimanja podataka sa visegsloja hijerarhije aplikacije i njihovo smestanje u bazu podataka i obrnuto –preuzimanje podataka iz baze podataka i njihovo prosledivanje visem slojuaplikacije. Direktna komunikacija sa bazom podataka ima svoje nedostatke,kao sto su: zavisnosti aplikacije od konkretnog SUBP-a, zavisnosti aplikacijeod izmena u bazi podataka, itd. Dakle, pozeljno je definisati neki vid pres-likavanja objekata iz objektno-orijentisanih aplikacija u svet relacionih bazapodataka. Za ove potrebe je moguce koristiti i nerelaciona resenja, ali je zavecinu aplikacija podrazumevano da se podaci cuvaju u relacionim bazamapodataka (cesto je razlog za to taj sto se baza podataka koristi i deli izmeduvise razlicitih aplikacija).

Resenje ovog problema pruzaju alati za objektno-relaciono preslikavanjekoji vrse automatsko preslikavanje relacionog modela baze podataka na ob-jektni model aplikacije. Oni omogucavaju da objektno-orijentisane aplikacijene rade direktno sa tabelarnom reprezentacijom podataka vec da imaju svojobjektno-orijentisani model. Kao sto je i ocekivano, prilikom pokusaja pres-likavanja jedne paradigme u drugu, javljaju se razliciti problemi i tada gov-orimo o objektno-relacionom neslaganju. U ovom poglavlju bice izlozeni oviproblemi i nakon toga bice prikazano kako koristiti alat Hibernate da bi seizborili sa njima.

77

Page 78: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

78GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

4.1 Objektno-relaciono preslikavanje

Trajnost podataka

Trajnost ili perzistentnost podataka (engl. data persistence) jedan je od os-novnih koncepata koji se podrazumevaju prilikom razvoja aplikacije. Uko-liko informacioni sistem nije sacuvao podatke prilikom iskljucivanja, on teskomoze biti od neke prakticne koristi. Trajnost objekata podrazumeva da poje-dinacni objekti mogu da nadzive izvrsavanje aplikacije; oni se mogu sacuvatiu skladistu podataka i iznova napraviti u nekom kasnijem trenutku. Kadase govori o pojmu trajnosti u programskom jeziku Java, obicno se misli napreslikavanje i cuvanje instanci objekata u bazi podataka koriscenjem SQL-a.

Relacione baze podataka

Relaciona tehnologija je danas najzastupljenija zbog svojih dobrih osobina,izmedu ostalog zbog svog fleksibilnog i robusnog pristupa upravljanju po-dacima. Zbog veoma dobro proucenih teorijskih osnova relacionog modelapodataka, relacione baze podataka garantuju i cuvaju integritet podataka.

Naravno, relacioni sistemi za upravljanje bazama podataka nisu specificniza programski jezik Java, niti je SQL baza podataka specificna za neku odredenuaplikaciju. Ovaj vazan princip je poznat kao nezavisnost podataka. Drugimrecima, podaci zive duze od svake aplikacije, a relaciona tehnologija dajemogucnost deljenja podataka izmedu razlicitih aplikacija ili medu razlicitimdelovima istog sistema. Kaze se i da je relaciona tehnologija “zajednicki delilac”mnogih razlicitih sistema i platformi.

Koriscenje SQL-a u Javi

Kada radimo sa SQL bazom podataka u Java aplikaciji, pozivamo SQL naredbenad bazom podataka koriscenjem JDBC API-a. Bez obzira na to da li je SQLkod bio rucno napisan i ugraden u Java kod ili je bio generisan u hodu ko-riscenjem Java koda, JDBC API se koristi za vezivanje argumenata prilikompripreme parametara upita, za izvrsavanja upita, kretanje kroz rezultat upita,izdvajanje vrednosti iz rezultujuceg skupa itd. Svi ovi zadaci kojima se pris-tupa podacima su niskog nivoa. Ono sto bi bilo pozeljno jeste napisati kodkoji cuva i izdvaja instance nasih klasa, oslobadajuci nas na taj nacin napornogposla koji je niskog nivoa. S obzirom na to da navedeni zadaci pristupa po-dacima mogu biti mukotrpni, pitanje je da li je relacioni model podataka iposebno SQL pravi izbor za obezbedivanje trajnosti u objektno-orijentisanimaplikacijama. Odgovor na ovo pitanje glasi da da u vecini situacija to jestedobar izbor.

Objektni svet je napravljen sa ciljem resavanja specificnih problema: buki-ranja leta, transfera novca, kupovine knjige itd. Tehnicka resenja problemase dizajniraju imajuci na umu model domena. Model domena definise ob-jekte koji predstavljaju probleme iz realnog sveta. Rezervacija leta, bankovniracun ili potraga za knjigom su primeri objekata iz domena. Za ove domenskeobjekte se ocekuje da budu sacuvani i izdvojeni iz baze podataka. Mnogeaplikacije iz realnog sveta ne mogu da postoje bez neke forme trajnosti. Za-mislimo da smo dobili informaciju od banke da su izgubili nas novac jer nisu

Page 79: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.1. OBJEKTNO-RELACIONO PRESLIKAVANJE 79

sacuvali nas depozit u trajnom prostoru za skladistenje. Takode, bili bismoveoma ljuti na aviokompaniju ako bismo kupili kartu a zatim otkrili da ne-mamo rezervaciju za let na zeljeni dan. Od svih dostupnih izbora, trajnostrelacionih baza podataka je industrijski standard za trajno skladistenje. Rela-cione baze podataka cuvaju podatke u dvodimenzionom formatu koji se sas-toji iz redova i kolona.

U okviru ovog poglavlja, razmatracemo probleme cuvanja podataka i nji-hovog deljenja u kontekstu objektno-orijentisane aplikacije koja koristi modeldomena. Umesto da se direktno radi sa redovima i kolonama rezultujucegskupa java.sql.ResultSet, poslovna logika aplikacije interaguje sa objektno-orijentisanim modelom domena koji je specifican za aplikaciju. Npr, ako SQLshema baze podataka ima tabelu Knjiga, Java aplikacija definise klasu Knjiga.Umesto da cita i pise vrednosti pojedinacnog reda i kolone, aplikacija ucitavai cuva instance klase Knjiga.

Naravno, nisu sve Java aplikacije dizajnirane na ovaj nacin, niti bi tre-balo da budu. Jednostavne aplikacije mogu raditi mnogo bolje bez modeladomena. Treba koristiti JDBC ResultSet ako je to sve sto nam je potrebno.Ali u slucaju aplikacija sa netrivijalnom poslovnom logikom, pristup modeladomena pomaze da se znacajno popravi ponovno koriscenje koda i njegovoodrzavanje.

Objektno-relaciono neslaganje

Vec desetinama godina, programeri govore o neskladu koji postoji medu ra-zlicitim paradigmama. Ovaj nesklad objasnjava zasto se u svaki projekat ulazedosta napora u brigu o trajnosti podataka.

Kombinacija objektne i relacione tehnologije moze da dovede do koncep-tualnih i tehnickih problema. Ti problemi su poznati kao objektno-relaciononeslaganje (engl. impedance mismatch). Medu najvaznije probleme spadaju:

• neslaganje izmedu nivoa granularnosti u objektno-orijentisanom mod-elu i odgovarajucem relacionom modelu,

• neslaganje hijerarhijskog uredenja podataka - medu tabelama u rela-cionoj bazi ne postoji mogucnost izgradnje hijerarhije, dok se objektimogu organizovati hijerarhijski,

• neslaganje pravila koja vaze za istovetnost – npr. dva reda u tabeli kojasadrze iste podatke smatraju se istim, te iz tog razloga nije dozvoljenounosenje dva ista reda u bazu, dok objekti koji sadrze iste podatke mogubiti razliciti jer imaju razlicite memorijske adrese,

• neslaganje u nacinima na koji se realizuju veze,

• neslaganje u nacinu na koji se pristupa podacima u Javi i u relacionimbazama podataka.

Svaki od ovih problema ilustrovacemo na jednom primeru.Pretpostavimo da treba da dizajniramo i implementiramo aplikaciju za on-

lajn elektronsku trgovinu. U ovoj aplikaciji potrebna je klasa za predstavljanjeinformacija o korisniku sistema i druga klasa za predstavljanje informacija oracunima korisnika, kao sto je prikazano na slici 4.1.

Page 80: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

80GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Slika 4.1: Jednostavni UML dijagram entiteta Korisnik i Racun

Sa ovog dijagrama jasno se vidi da jedan korisnik moze da ima vise racuna.Iz svake klase moze se pristupiti drugom kraju veze. Ovo se realizuje takosto se svakoj klasi doda odgovarajuca instanca druge klase. Klase kojima sepredstavljaju ovi entiteti mogu biti vrlo jednostavne:

public class Korisnik{

String korisnicko_ime;

String adresa;

Set racuni;

// metode za pristup (get/set), itd.

}

public class Racun{

String racun;

String naziv_banke;

Korisnik korisnik;

// metode za pristup (get/set), itd.

}

U ovom slucaju nije tesko doci do dizajna odgovarajuce SQL sheme:

create table Korisnici (

korisnicko_ime varchar(15) not null primary key,

adresa varchar(255) not null

);

create table Racun (

racun varchar(15) not null primary key,

naziv_banke varchar(255) not null,

korisnicko_ime varchar(15) not null,

foreign key (korisnicko_ime) references Korisnici

);

Kolona korisnicko ime u tabeli Racun sa koje pravimo strani kljuc pred-stavlja odnos izmedu dva entiteta. Za ovaj jednostavan model domena, objektno-relaciono neslaganje se skoro i ne primecuje. Pravolinijski je napisati odgo-varajuci JDBC kod za umetanje, azuriranje i brisanje informacija o korisnicimai racunima.

Medutim, neslaganje ove dve paradigme bice vidljivije kada se aplikacijidoda jos entiteta i odnosa izmedu entiteta.

Page 81: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.1. OBJEKTNO-RELACIONO PRESLIKAVANJE 81

Problem granularnosti

U prethodnom primeru adresa je bila vrednost tipa String. U mnogim pri-menama potrebno je posebno sacuvati informaciju o ulici, gradu i postanskomkodu. Moguce je, naravno, dodati sve ove podatke direktno u klasu Korisnik

ali s obzirom na to da je moguce da druge klase u sistemu takode imaju infor-maciju o adresi, ima vise smisla napraviti zasebnu klasu Adresa. Na slici 4.2prikazan je dopunjeni model.

Slika 4.2: Model u kome korisnik ima informaciju o adresi

Da li bi, takode, trebalo dodati i tabelu Adresa? To nije neophodno, vec jeuobicajeno cuvati informaciju o adresi u tabeli Korisnici u posebnim kolona-ma. U ovom scenariju nije potrebno spajati tabele ako je potrebno dobiti ko-risnika i adresu u jednom upitu. Mozda bi najbolje resenje bilo da se napravinovi SQL tip podataka za predstavljanje adrese i da se tabeli Korisnici dodajedna nova kolona umesto vise njih. Dakle, imamo izbor da tabeli Korisnicidodamo vise kolona ili jednu kolonu (novog SQL tipa podataka). Ovde seocito javlja problem granularnosti. Granularnost se odnosi na relativne velicinetipova sa kojima radimo. Vratimo se prethodnom primeru i dodajmo tabeliKorisnici kolonu koja je novog tipa podataka:

create table Korisnici (

korisnicko_ime varchar(15) not null primary key,

adresa address not null

);

Novi tip podataka Adresa (klasa) u Javi i novi SQL tip podataka address

bi trebalo da omoguce kompatibilnost. Medutim, ukoliko proverimo kakva jepodrska za korisnicki definisane tipove podataka u danasnjim sistemima zaupravljanje bazama podataka susrescemo se sa mnogim problemima, stogakoriscenje korisnicki definisanih tipova nije praksa u industrijskim aplikaci-jama. Pragmaticno resenje ovog problema se sastoji u dodavanju nekolikokolona koje su osnovnih SQL tipova podataka:

create table Korisnici (

korisnicko_ime varchar(15) not null primary key,

adresa_ulica varchar(255) not null,

adresa_kod varchar(5) not null,

adresa_grad varchar(255) not null

);

Klase u Java modelu domena dolaze u razlicitim nivoima granularnosti:od klasa entiteta kao sto je Korisnik, do finijih klasa kao sto je Adresa, dojednostavnih klasa kao sto bi recimo bio PostanskiKod koji nasleduje klasuApstraktniPostanskiKod.

Page 82: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

82GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

S druge strane, u SQL bazama podataka postoje samo dva tipa granu-larnosti: tipovi relacija koje mi kreiramo, kao sto su recimo relacije Korisnici

i Racun i ugradeni tipovi podataka kao sto su VARCHAR, BIGINT, . . .

Problem podtipova

U Javi se nasledivanje implementira koriscenjem mehanizma natklasa i potk-lasa. Dodajmo prethodnom primeru mogucnost da aplikacija moze da prih-vati ne samo naplatu sa racuna u banci, vec i sa kreditnih i debitnih kartica.Prirodan nacin da se ova promena izvede jeste koriscenjem natklase Racun, za-jedno sa nekoliko konkretnih potklasa: TekuciRacun, DevizniRacun,. . . Svakaod ovih potklasa definise neznatno izmenjene podatke (i potpuno drugaci-je funkcionalnosti koje se izvode na tim podacima). UML klasni dijagramprikazan na slici 4.3 ilustruje ovaj model.

Slika 4.3: Koriscenje mehanizma nasledivanja za razlicite strategije placanja

Koje izmene u bazi podataka treba izvesti da bi podrzali izmenjene Javaklasne strukture? SQL baza podataka u opstem slucaju ne implementira na-sledivanje tabela (cak ni nasledivanje tipova podataka). Takode, cim se uvedepojam nasledivanja, postoji mogucnost polimorfizma. Klasa Korisnik imadefinisanu vezu ka natklasi Racun. Ovo je polimorfna veza. U vreme izvrsavanjainstanca Korisnik moze da referise na instancu bilo koje potklase klase Racun.Slicno, zelimo da omogucimo da pisemo polimorfne upite koji referisu na klasuRacun a da upit vrati instancu neke potklase.

SQL bazama podataka nedostaje nacin za predstavljanje polimorfne veze.Ogranicenje stranog kljuca se odnosi na tacno jednu ciljnu tabelu i nije pravolin-ijski definisati strani kljuc koji referise na vise tabela. U te svrhe morali bismonapisati proceduralno ogranicenje koje bi nametalo ovu vrstu pravila integriteta.

Rezultat neslaganja podtipova je da struktura nasledivanja u modelu trebabiti ocuvana u SQL bazi podataka koja ne nudi mehanizam nasledivanja.

Problem istovetnosti

Na problem istovetnosti se nailazi u situaciji kada je potrebno proveriti da lisu dve instance identicne. Naime, postoje tri nacina na koja se ovaj problemmoze dotaci: dva u kontekstu Jave i jedan u kontekstu SQL baze podataka.Java definise dva razlicita pojma istovetnosti:

• identicnost instanci, koja se odnosi na ekvivalentnost memorijskih loka-cija i proverava se sa a == b

Page 83: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.1. OBJEKTNO-RELACIONO PRESLIKAVANJE 83

• jednakost instanci, koja se utvrduje implementacijom metoda equals()

– na ovu jednakost se cesto referise kao na jednakost prema vrednosti

S druge strane, istovetnost redova baze podataka se izrazava kao poredenjevrednosti primarnih kljuceva tih redova. Medutim, niti koriscenje metodaequals() niti operatora == nije uvek ekvivalentno poredenju vrednosti pri-marnog kljuca. Uobicajeno je da nekoliko neidenticnih instanci u Javi istovre-meno predstavlja isti red u bazi podataka – na primer, u nitima aplikacije kojese konkurentno izvrsavaju.

Razmotrimo jos jedan problem koji se javlja u vezi sa pojmom istovetnostiu bazama podataka. Polje korisnicko ime je primarni kljuc tabele Korisnik.Nazalost, ova odluka otezava promenu korisnickog imena; potrebno je azuriratine samo odgovarajuci red u tabeli Korisnik, vec i vrednosti stranog kljucau (potencijalno mnogim) redovima tabele Racun. Da bi se resio ovaj prob-lem, cesto se savetuje koriscenje surogat kljuceva. Pod surogat kljucem po-drazumevamo kolonu koja cini primarni kljuc i koja nema nikakvo znacenjekorisniku aplikacije – drugim recima kljuc koji se ne prikazuje korisniku ap-likacije. Njegova jedina svrha jeste identifikacija podataka unutar aplikacije.Na primer, mozemo izmeniti definicije tabela na sledeci nacin:

create table Korisnici(

ID bigint not null primary key,

korisnicko_ime varchar(15) not null unique,

...

);

create table Racun(

ID bigint not null primary key,

racun varchar(15) not null,

naziv_banke varchar(255) not null,

ID_korisnika bigint not null,

foreign key (ID_korisnika) references Korisnici

);

Kolone ID sadrze vrednosti koje su sistemski generisane i koje su uve-dene iskljucivo zbog koristi modela podataka, tako da ostaje pitanje kako (akouopste) treba da budu prikazane u modelu Java domena.

Problemi asocijacija (veza)

U modelu domena, asocijacije (veze) predstavljaju odnose izmedu entiteta.Klase Korisnik, Adresa i Racun su medusobno povezane. Ali za razliku odklase Adresa, klasa Racun jeste samostalna. Instance klase Racun se cuvaju usvojoj vlastitoj tabeli. Preslikavanje veza i upravljanje vezama izmedu entitetasu centralni koncepti u svakom resenju trajnosti objekata.

Objektno-orijentisani jezici predstavljaju veze koriscenjem referenci na ob-jekte; u relacionom svetu, veza se predstavlja kolonom stranog kljuca kojasadrzi kopiju vrednosti kljuca. Postoje znacajne razlike izmedu ova dva meh-anizma. Reference na objekte su sustinski usmerene; veza “ide” od jedne in-stance ka drugoj. One su pokazivaci. Ako bi veza izmedu instanci trebalo

Page 84: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

84GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

da bude pristupacna u oba smera, veza bi se morala definisati dva puta, pojednom u svakoj od klasa koje treba povezati.

public class Korisnik {

Set racuni;

}

public class Racun {

Korisnik korisnik;

}

Navigacija koja je usmerena u odredenom smeru u relacionom modelupodataka nema smisla jer je moguce napraviti proizvoljnu vezu izmedu po-dataka koriscenjem operatora spajanja i operatora projekcije. Veze u Javi moguda budu tipa vise ka vise. Na primer, prethodne klase mogu imati naredni ob-lik:

public class Korisnik {

Set racuni;

}

public class Racun {

Set korisnici;

}

Deklaracija stranog kljuca u tabeli Racun predstavlja vezu tipa “vise kajedan”: svaki racun u banci vezan je za jednog korisnika, dok svaki korisnikmoze da poseduje vise bankovnih racuna. Ako zelimo da u SQL bazama po-dataka predstavimo vezu tipa “vise ka vise” potrebno je uvesti novu tabelu,koju najcesce nazivamo veznom tabelom. U vecini slucajeva ova tabela se nejavlja nigde u modelu domena. Za ovaj primer, ako bismo razmatrali da jeveza izmedu korisnika i racuna tipa vise ka vise, definisali bismo veznu tabeluna sledeci nacin:

create table Korisnik_Racun (

ID_korisnika bigint,

ID_racuna bigint,

primary key (ID_korisnika, ID_racuna),

foreign key (ID_korisnika) references Korisnici,

foreign key (ID_racuna) references Racun

);

U ovoj situaciji vise nije potrebna kolona stranog kljuca i odgovarajuceogranicenje stranog kljuca u tabeli Racun; ova dodatna tabela sada kontrolisevezu izmedu dva entiteta.

Problem navigacije podataka

Postoji osnovna razlika u tome kako se pristupa podacima u Javi a kako u rela-cionim bazama podataka. U Javi kada se pristupa informacijama o racunimanekog korisnika, imamo poziv ovog oblika:

Page 85: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.1. OBJEKTNO-RELACIONO PRESLIKAVANJE 85

nekiKorisnik.getRacun().iterator().next()

Ovo je najprirodniji nacin da se pristupi podacima objektno-orijentisane paradigme.Na ovaj nacin krece se od jedne instance ka drugoj, prateci pripremljene poka-zivace izmedu klasa. Nazalost, ovo nije efikasan nacin za dobijanje podatakaiz SQL baze podataka.

Mozda najznacajnija stvar koju mozemo uraditi da popravimo performansepristupa podacima jeste da se minimizuje broj zahteva nad bazom podataka.Ocigledan nacin da se to uradi jeste da se minimizuje broj SQL upita. Stogase za efikasan pristup relacionim podacima koriscenjem SQL-a obicno za-hteva spajanje tabela od interesa. Broj tabela koje su ukljucene u spajanjeodreduje dubinu mreze objekata kojom se krecemo po memoriji. Na primer,ako hocemo da izdvojimo korisnika, a nisu nam od znacaja informacije vezaneza korisnikove racune, mozemo zeljene informacije dobiti koriscenjem nared-nog upita:

select * from Korisnici k

where k.ID = 123

S druge strane, ako je potrebno izdvojiti korisnika, a onda naknadno posetitisvaku od pridruzenih instanci Racun (recimo da izlistamo sve bankovne racunekorisnika) pisali bismo drugaciji upit:

select * from Korisnici k

left outer join Racun r

on r.ID_korisnika = k.ID

where k.ID = 123

Kao sto mozemo videti, da bismo efikasno koristili spajanja potrebno jeznati kom delu mreze objekta planiramo da pristupamo. Ukoliko izdvojimoprevise podataka, rasipamo memoriju na nivou aplikacije.

SQL bazu podataka mozemo, takode, opteretiti i velikim dekartovskimproizvodima. Zamislimo da u jednom upitu ne izdvajamo samo korisnike ibankovne racune, vec takode i sve narudzbine placene sa svakog od racuna isve proizvode u svakoj od narudzbina itd.

Svako resenje koje ukljucuje trajnost objekata obezbeduje funkcionalnostza izdvajanje podataka iz povezanih instanci tek kada se toj vezi prvo pristupiu Java kodu. Ovaj efekat je poznat kao lenjo ucitavanje (engl. lazy loading),odnosno preuzimanje podataka (tj. materijalizacija slogova baze podataka uobjekte programa) vrsi se samo na zahtev, tj. u trenutku kada su oni potrebni(kada im se pristupi u kodu).

Ovakav stil pristupanja jednom po jednom podatku je neefikasan u kon-tekstu SQL baza podataka, jer zahteva izvrsavanje jedne naredbe za svakiod cvorova ili kolekciju objekata mreze kojoj se pristupa. Ovo neslaganje unacinu na koji se pristupa podacima u Javi i relacionim bazama podataka jemozda i najcesci uzrok problema vezanih za performanse Java informacionogsistema. Hibernate obezbeduje sofisticirane metode za efikasno i transpar-entno dohvatanje mreza objekata iz baze podataka do aplikacije koja im pris-tupa.

Page 86: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

86GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

ORP i JPA

U sustini, objektno-relaciono preslikavanje (ORP) je automatsko (i transpar-entno) trajanje objekata iz Java aplikacije u tabelama SQL baze podataka, ko-riscenjem metapodataka koji opisuju preslikavanja izmedu klasa aplikacije isheme SQL baze podataka. ORP radi tako sto transformise podatke iz jednereprezentacije u drugu. Hibernate je jedan od alata kojima se moze izvestiobjektno-relaciono preslikavanje.

Razmotrimo neke prednosti koriscenja alata Hibernate:

• produktivnost – Hibernate eliminise vecinu zamornog posla i omogu-cava da se programer skoncentrise na poslovnu logiku problema. Bezobzira koju strategiju razvoja aplikacije koristimo: odozgo-nanize (pocevod modela domena) ili odozdo-navise (pocev od postojece sheme bazepodataka) Hibernate koriscen sa odgovarajucim alatima znacajno sman-juje vreme razvoja.

• pogodnost odrzavanja – automatsko izvrsavanje objektno-relacionog pre-slikavanja smanjuje broj linija koda, cineci na taj nacin sistem razumljivi-jim i jednostavnijim za refaktorisanje. Hibernate predstavlja “bafer”izmedu modela domena i SQL sheme, izolujuci na taj nacin svaki odovih modela od malih izmena drugog.

• performanse – iako rucno kodiranje trajnosti moze biti brze u istomsmislu kao sto je kod u asembleru brzi od Java koda, automatska resenjakao sto je Hibernate omogucavaju koriscenje raznih vidova optimizacije.Ovo znaci da programeri mogu da potrose vise energije na rucno opti-mizovanje nekoliko preostalih uskih grla, umesto da prerano sve opti-mizuju.

• nezavisnost od proizvodaca – Hibernate moze da doprinese smanjivanjurizika koji su povezani sa situacijom da korisnik postane zavisan odproizvodaca nekog proizvoda ili usluge, bez mogucnosti da koristi us-luge drugog proizvodaca, bez znacajnijih troskova. Cak iako se nikadane planira izmena SUBP proizvoda, ORP alati koji podrzavaju razliciteSUBP-ove omogucavaju odredeni nivo portabilnosti. Dodatno, nezav-isnost od SUBP-a pomaze u scenariju gde se tokom razvoja koristi jed-nostavna lokalna baza, a testiranje i proizvodnja rade na drugacijem sis-temu.

Hibernate pristup trajnosti podataka je dobro primljen od strane Java pro-gramera i napravljen je standardizovani Java Persistence API (JPA). JPA speci-fikacijom se definise:

• mogucnost zadavanja metapodataka preslikavanja – kako se trajne klasei njihova svojstva odnose na shemu baze podataka. JPA se u velikojmeri oslanja na Java anotacije u klasama modela domena, ali se, takode,preslikavanja mogu zadavati koriscenjem XML datoteka,

• API za izvodenje osnovnih CRUD operacija1 (create, read, update, delete)na instancama trajnih klasa, pre svega javax.persistence.EntityManagerza cuvanje i ucitavanje podataka,

1CRUD je akronim za cetiri osnovne funkcije trajnog skladista.

Page 87: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 87

• jezik i API za zadavanja upita koji se odnose na klase i svojstva klasa.Ovaj jezik naziva se Java Persistence Query Language (JPQL) i nalik jeSQL-u. Standardizovani API omogucava programsko kreiranje kriteri-juma upita bez manipulacije stringovima

• kako mehanizam trajnosti interaguje sa instancama transakcija da bi seizvele optimizacione funkcije.

Hibernate implementira JPA i pruza podrsku za sva standardna preslika-vanja, upite i programske interfejse.

Dakle, objektno-relaciono preslikavanje je nastalo kao trenutno najboljeresenje za objektno-relaciono neslaganje. Na primer, mreza objekata ne mozebiti sacuvana u tabeli baze podataka: ona mora biti rastavljena na koloneportabilnih SQL tipova podataka. Zadatak ORP-a je da programera oslobodiod 95% posla obezbedivanja trajnosti objekata, kao sto su pisanje slozenih SQLupita koji ukljucuju mnoga spajanja tabela i kopiranje vrednosti iz JDBC rezul-tujuceg skupa u objekte ili grafove objekata.

4.2 Hibernate

Razmotrimo Java aplikaciju MenadzerKnjiga ciji je glavni zadatak da sacuvaknjigu u bazi podataka o knjigama, da pronade odredenu knjigu i izdvoji je izbaze podataka. Za ove potrebe koristicemo bazu podataka o knjigama i tabeluKnjige, prikazanu na slici 4.1.

k sifra naziv izdavac god izdavanja105 Na Drini Cuprija Prosveta 1978107 Prokleta Avlija Nova knjiga 1990203 Beograd veciti grad Skordisk 2010

Tabela 4.1: Tabela Knjige

Svaki red tabele Knjige predstavljace instancu klase Knjiga u aplikacijiMenadzerKnjiga.

Iz perspektive objektno-orijentisanog programera, bilo bi lepo kada bismomogli da pozovemo metod sacuvajKnjigu() u korisnickoj klasi sa ciljem dasacuvamo objekat Knjiga. Da bismo postigli ovaj cilj, kreiracemo klasu u Javikoja predstavlja knjigu. Za svaku knjigu koju treba da bude izdata, napravi-cemo novi objekat tipa Knjiga. Ovo je moguce uraditi na sledeci nacin:

public class Knjiga{

private int id_knjige = 0;

private String naziv = null;

private String izdavac = null;

private int god_izdavanja = 0;

...

// preskacemo set/get metode

}

Page 88: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

88GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Ono sto je dalje potrebno jeste omoguciti da se ovaj objekat trajno sacuvau tabeli Knjige baze podataka, odnosno da se objektni model (objekat tipaKnjiga) konvertuje u relacioni model (red tabele Knjige). Kreirajmo klasuKnjigaTrajno koja treba da uradi ovaj posao:

public class KnjigaTrajno {

public void sacuvajKnjigu(Knjiga knjiga){

// ovde ide kod kojim se knjiga trajno cuva

}

public Knjiga izdvoji(String naziv) {

// ovde ide kod kojim se knjiga izdvaja na osnovu naziva

}

...

}

Iako metodama jos uvek nismo dodali potrebnu funkcionalnost, pogleda-jmo kako je jednostavno trajno sacuvati knjigu koriscenjem pomocne klase(engl. utility class) KnjigaTrajno:

KnjigaTrajno knjigaTrajno = new KnjigaTrajno();

Knjiga knjiga = new Knjiga();

knjiga.setId_knjige(101);

knjiga.setNaziv("Norveska suma");

knjiga.setIzdavac("Geopoetika");

knjiga.setGod_izdavanja(2007);

knjigaTrajno.sacuvajTrajno(knjiga);

Dakle, knjiga se trajno skladisti kao red tabele koriscenjem pomocne klase.Da bismo metodama sacuvajKnjigu i izdvoji dodali potrebnu funkcional-nost, neophodna nam je konekcija sa bazom podataka, zatim mehanizam ko-jim se objekat konvertuje u red tabele (kao i preslikavanje svojstava objekatau kolone tabele). Mogli bismo sami osmisliti mehanizam kojim bi se ovopostiglo, ali ovo je moguce uraditi i koriscenjem okruzenja Hibernate kojimse objekti trajno cuvaju u relacionoj bazi podataka. Metod za cuvanje knjigebi u Hibernate-u bio refaktorisan na sledeci nacin:

public class OsnovniMenadzerKnjiga{

private void sacuvajKnjigu(Knjiga knjiga) {

Session sesija = sessionFactory.getCurrentSession();

...

sesija.save(knjiga);

}

...

}

Primetimo da se instanca Knjiga cuva u bazi podataka izvrsavanjem jednejedine linije koda: sesija.save(knjiga), kao sto smo i zeleli u prethodnomrazmatranju koriscenja pomocne klase. API klase alata Hibernate sadrze neko-liko metoda za jednostavno manipulisanje Java objektima. Naravno, potrebnoje Hibernate-u dostaviti konfiguraciju, kao i preslikavanje kojim se zadajunase namere.

Page 89: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 89

Koriscenje Hibernate okruzenja

Standardni koraci koje pratimo prilikom pravljenja Hibernate aplikacije su:

1. konfigurisanje konekcije na bazu podataka,

2. kreiranje definicije preslikavanja,

3. trajno cuvanje klasa.

U nastavku je dat spisak uobicajenih koraka koje treba primeniti u razvojuJava-Hibernate verzije aplikacije MenadzerKnjiga:

1. kreirati objekat sa domenom Knjige (modeli domena predstavljaju tabele),

2. kreirati konfiguracione datoteke kao sto su Hibernate svojstva i datotekesa preslikavanjima,

3. kreirati testnog klijenta koji barata knjigama (dodaje/azurira/brise/traziknjigu).

Glavna stvar Hibernate aplikacije jeste njeno konfigurisanje. Postoje dvadela konfiguracije koja se zahteva u svakoj Hibernate aplikaciji: jedna pravikonekciju na bazu podataka, a druga kreira preslikavanje objekata na tabele:njome se definise koja se svojstva objekata preslikavaju u koje kolone tabele.

Konfigurisanje konekcije na bazu podataka

Da bi se povezali na bazu podataka, Hibernate mora da zna detalje o bazi po-dataka, tabelama, klasama itd. Ove informacije se mogu proslediti posred-stvom XML datoteke (koja se uobicajeno naziva hibernate.cfg.xml) ili uvidu jednostavne tekstualne datoteke koja sadrzi parove oblika ime/vrednost(ciji je podrazumevani naziv hibernate.properties). U nastavku ce biti pri-kazano kako se ove informacije prosleduju u vidu XML datoteke (naziv da-toteke je hibernate.cfg.xml, te okruzenje automatski ucitava ovu datoteku).

<hibernate-configuration>

<session-factory>

<property name="dialect">

org.hibernate.dialect.DB2Dialect

</property>

<property name="connection.driver_class">

com.ibm.db2.jcc.DB2Driver

</property>

<!-- Pretpostavimo da je ime baze podataka test -->

<property name="connection.url">

jdbc:db2://localhost:50001/test

</property>

<!-- Pretpostavimo da je korisnicko ime korisnicko_ime,

a sifra korisnik_sifra -->

<property name="connection.username">

korisnicko_ime

</property>

Page 90: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

90GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

<property name="connection.password">

korisnik_sifra

</property>

<!-- Ovde ide lista XML datoteka koje sadrze preslikavanja -->

<mapping resource="Knjiga.hbm.xml" />

<mapping resource="Biblioteka.hbm.xml" />

</session-factory>

</hibernate-configuration>

Ova svojstva je moguce zadati i u vidu parova ime/vrednost. Na primer,jedan deo datoteke hibernate.properties bi izgledao ovako:

hibernate.dialect = org.hibernate.dialect.DB2Dialect

hibernate.connection.driver_class = com.ibm.db2.jcc.Driver

hibernate.connection.url = jdbc:db2://localhost:50001/test

Kao sto mozemo da primetimo u ovom pristupu sva svojstva imaju prefiks“hibernate”.

U okviru ovih konfiguracionih datoteka, svojstvo connection.url sadrziURL adresu na koju se treba povezati, driver class na relevantnu klasu dra-jvera potrebnu za pravljenje konekcije, a dialect na dijalekt baze podatakakoji koristimo (u okviru kursa izucava se DB2 dijalekt). Pored konfigura-cionih svojstava potrebno je ukljuciti i datoteke koje sadrze preslikavanja i nji-hove lokacije. Ova preslikavanja se zadaju u posebnim datotekama sa sufik-som .hbm.xml. U okviru konfiguracione datoteke se koristi element mapping iatribut resource koji ukazuje na resurs koji sadrzi preslikavanja i koji Hiber-nate treba da ucita (u prikazanom primeru, recimo datoteka Knjiga.hbm.xml

sadrzi detalje o tome kako se objekat Knjiga preslikava na tabelu Knjige).Sta Hibernate dalje radi sa datotekom koja sadrzi data svojstva? Naime,

Hibernate okruzenje ucitava ovu datoteku da bi napravio kreator sesija (fabrikusesija) SessionFactory, koja je globalna fabricka klasa za kreiranje sesija i njumogu na bezbedan nacin koristiti vise niti u isto vreme (engl. thread-safe). Uidealnom slucaju potrebno je kreirati jednog kreatora sesija i deliti ga meduaplikacijama. Medutim, treba primetiti da je on definisan za jednu i samojednu bazu podataka. Stoga, ako imamo potrebu za jos jednom bazom po-dataka potrebno je definisati relevantnu konfiguraciju u datoteci hibernate.hbm.xmlda bismo kreirali posebnog kreatora sesija SessionFactory za tu bazu po-dataka. Kao sto i sam naziv kaze, cilj kreatora sesije je kreiranje objekatasesija. Sesija predstavlja “prolaz” do nase baze podataka. Zadatak sesijejeste da vodi racuna o svim operacijama nad bazom podataka kao sto sucuvanje, ucitavanje i izdvajanje podataka iz relevantnih tabela. Okruzenje,takode, predstavlja i posrednika u rukovodenju transakcijama u okviru ap-likacije. Operacije koje ukljucuju pristup bazi podataka su “upakovane” ujedinstvenu celinu posla – jednu transakciju. Sve operacije u okviru transak-cije se ili uspesno zavrsavaju ili se ponistavaju.

Treba imati na umu da se konfiguracije koriste za kreiranje sesija preko in-stance kreatora sesija. Pomenimo da objekat Session nije bezbedno koristitiod strane vise niti u isto vreme (tj. Session je jedno-nitni objekat) i stoga ihne treba deliti izmedu razlicitih klasa. Takode, obzirom da ih nije bezbednokoristiti od strane vise niti u isto vreme (kazemo i da nisu thread-safe) objekat

Page 91: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 91

sesije ne bi trebalo da bude otvoren neki duzi vremenski period. Koristimopoziv fabrika.getCurrentSession() da dobijemo tekucu sesiju iz fabrikesesija.

Jednom kada imamo objekat sesije mozemo izvoditi operacije nad bazompodataka u okviru transakcije. Sesija i transakcija idu ruku pod ruku. Uobicajenzivotni ciklus sesije i transakcije prikazan je u narednom fragmentu koda:

// trazimo tekucu sesiju

Session sesija = fabrika.getCurrentSession();

// kreiramo transakciju i zapocinjemo je

Transaction tr = sesija.getTransaction();

tr.begin();

// izvodimo operacije nad bazom podataka unutar sesije

// kada zavrsimo, potvrdjujemo transkaciju i sesiju

tr.commit();

Oba razmatrana metoda (svojstva i XML datoteke) su deklarativna. Hiber-nate, takode, podrzava i programsko konfigurisanje, prikazano u narednomfragmentu koda:

Configuration konf = new Configuration();

konf.setProperty("hibernate.dialect",

"org.hibernate.dialect.DB2Dialect");

konf.setProperty("hibernate.connection.username", korisnicko_ime);

konf.setProperty("hibernate.connection.password", korisnik_sifra);

konf.setProperty("hibernate.connection.url",

"jdbc:db2://localhost:50001/test");

Alternativno, moguce je izvrsiti konfigurisanje koriscenjem odgovarajucekonfiguracione datoteke:

Configuration konf = new Configuration();

konf.configure("hibernate.cfg.xml");

Kreiranje definicija preslikavanja

Sada kada smo konfigurisali konekciju, potrebno je datoteku Knjiga.hbm.xml

popuniti definicijama preslikavanja objekata na tabele. Naredni fragment XMLkoda definise preslikavanje objekta Knjiga na tabelu Knjige:

<hibernate-mapping>

<class name="Knjiga" table="Knjige">

<id name="id_knjige" column="k_sifra">

<generator class="native"/>

</id>

<property name="naziv" column="naziv"/>

<property name="izdavac" column="izdavac"/>

<property name="god_izdavanja" column="god_izdavanja"/>

</class>

</hibernate-mapping>

Page 92: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

92GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Element <hibernate-mapping> sadrzi sve definicije preslikavanja klasana tabele. Pojedinacna preslikavanja objekta su deklarisana pod elementom<class>. Atribut name etikete <class> referise na domensku klasu Knjiga,dok atribut table referise na tabelu Knjige u kojoj se cuvaju objekti. Pre-ostala svojstva ukazuju na preslikavanja svojstava objekta na kolone tabele(npr. svojstvo id knjige objekta se preslikava u kolonu k sifra tabele). Svakiobjekat mora imati jedinstveni identifikator – nalik primarnom kljucu tabelei on se preslikava u primarni kljuc odgovarajuce tabele. Ovaj identifikatorpostavlja se koriscenjem etikete <id> i zadavanjem odgovarajuce strategije.Postoje razlicite strategije za automatsko generisanje ovih identifikatora. Onese zadaju atributom class u okviru elementa <generator>. Postoji nekolikougradenih generatora:

• increment – vrednost kolone celobrojnog tipa se automatski inkremen-tira, pocinje se uvek od 1 i uvek se inkrementira za 1,

• identity – vrednost kolone celobrojnog tipa se automatski inkremen-tira na osnovu vrednosti koju odredi baza podataka,

• sequence – vrednost kolone celobrojnog tipa se automatski inkremen-tira tako sto pitamo bazu podataka za narednu vrednost niza; moguceje postaviti korak inkrementiranja; prilikom trazenja naredne vrednosti,moguce je dohvatiti vise njih i zapamtiti ih i imati ih za naredne operacijeINSERT, stoga je ova strategija efikasnija od identity strategije,

• native – podrazumevana strategija, bira se identity ili sequence strate-gija u zavisnosti od toga sta baza podrzava,

• assigned – potrebno je da nasa aplikacija postavi jedinstveni identifika-tor.

Svako od ovih imena jeste skracenica odredene klase. Na primer, assignedje skracenica za klasu org.hibernate.id.Assigned.

Generatorima mozemo zadati potrebne argumente koriscenjem elemenataparam. Na primer, prilikom koriscenja strtegije sequence, mozemo zadati nizprema kome se vrsi postavljanje naredne vrednosti:

<id name="id_knjige" column="k_sifra">

<generator class="sequence">

<param name="sequence">Knjige_niz</param>

</generator>

</id>

Definicije preslikavanja ukazuju na to koji objekti ce biti trajno sacuvani i ukojoj tabeli. Dodatno, zadaju se svojstva objekta koja treba trajno sacuvati. El-ement <property> sluzi za definisanje polja u kojima ce biti sacuvana polja ob-jekta: na primer, polje izdavac objekta Knjiga bice sacuvano u koloni izdavac.Ukoliko je ime kolone isto kao i ime polja objekta, mozemo izostaviti deklara-ciju svojstva column. Stoga bi prethodni primer mogao da ima naredni oblik:

<hibernate-mapping>

<class name="Knjiga" table="Knjige">

Page 93: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 93

<id name="id_knjige" column="k_sifra">

<generator class="native"/>

</id>

<property name="naziv"/>

<property name="izdavac"/>

<property name="god_izdavanja"/>

</class>

</hibernate-mapping>

U prethodnom fragmentu koda, izostavili smo da pomenemo tipove po-dataka atributa. Na koji nacin Hibernate treba da zna da je atribut naziv tipaString, a atribut god izdavanja celobrojnog tipa? U opstem slucaju potrebnoje deklarisati i ove tipove, koriscenjem elementa type, na sledeci nacin:

<hibernate-mapping>

<class name="Knjiga" table="Knjige">

...

<property name="naziv" type="string"/>

<property name="izdavac" type="string"/>

<property name="god_izdavanja" type="integer"/>

</class>

</hibernate-mapping>

U principu mozemo izostaviti tipove i ostaviti da Hibernate smisli tipovepromenljivih, ali dobra praksa je eksplicitno navesti tipove, da Hibernate nato ne bi gubio vreme.

Najjednostavniji pristup je onaj u kome se preslikavanje trajnih klasa natabele baze podataka vrsi van koda, koriscenjem datoteka preslikavanja. Me-dutim, postoji jos jedan nacin da se ovo uradi. Java 5 je u jezik uvela anotacije(engl. annotations), koje su ubrzo prihvacene od strane mnogih okruzenja pai od strane Hibernate-a. Anotacije predstavljaju metapodatke o preslikavanjuobjekata na tabele i one se dodaju klasi na nivou izvornog koda. Anotacije nemenjaju, niti uticu na to kako radi izvorni kod.

U nastavku je prikazana izmenjena klasa Knjiga, u kojoj su preslikavanjadeklarisana koriscenjem anotacija na nivou klasa i promenljivih:

@Entity

@Table(name="Knjige")

public class Knjiga implements Serializable {

@Id

private int id_knjige = 0;

private String naziv = null;

private String izdavac = null;

private int god_izdavanja = 0;

...

// preskacemo set/get metode

}

Svaki trajni objekat se taguje (na nivou klase) koriscenjem anotacije @Entity.Anotacija @Table deklarise tabelu baze podataka gde ce se cuvati ovi entiteti.U principu ne moramo da obezbedimo anotaciju @Table ako je ime klase i

Page 94: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

94GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

tabele isto (u nasem slucaju se razlikuju pa je to neophodno uraditi). Anotacija@Id ukazuje da je promenljiva jedinstveni identifikator instance objekta (drugimrecima, primarni kljuc).

Hibernate koristi Java Persistence API (JPA) anotacije, te se prethodne an-otacije ucitavaju iz paketa javax.persistence.

Trajno cuvanje objekata

Napravimo sada klijenta koji trajno cuva objekte uz pomoc Hibernate alata.Potrebna nam je instanca SessionFactory klase pomocu koje kreiramo ob-jekat sesije. U nastavku je prikazano inicijalno podesavanje za pravljenje klaseSessionFactory:

public class OsnovniMenadzerKnjiga {

private SessionFactory fabrikaSesija = null;

private void inicijalizujFabrikuSesija(){

Configuration konf = new Configuration().configure();

// gradimo servisni registar koriscenjem konfiguracionih svojstava

ServiceRegistry servReg =

new ServiceRegistryBuilder().applySettings(

konf.getProperties()).buildServiceRegistry();

// pravimo fabriku sesija

fabrikaSesija = konf.buildSessionFactory(servReg);

}

...

}

Ukoliko nisu eksplicitno navedene datoteke koje sadrze preslikavanja, kon-figuraciju ili svojstva, podrazumeva se da se u putanji nalaze datoteke sa po-drazumevanim nazivima kao sto su: hibernate.cfg.xml ili hibernate.properties.Ako imena ovih datoteka nisu podrazumevana, onda se moraju navesti kaoargumenti odgovarajucih metoda.

Pravljenje metoda za trajno cuvanje objekata

Definisimo metod sacuvajKnjigu u okviru klase OsnovniMenadzerKnjiga ko-jim ce biti moguce trajno sacuvati knjigu. On treba da iskoristi metod save kojipostoji u okviru sesije. Ovaj mehanizam prikazan je u okviru sledeceg koda:

public class OsnovniMenadzerKnjiga{

private void sacuvajKnjigu(Knjiga knjiga) {

Session sesija = fabrikaSesija.getCurrentSession();

sesija.beginTransaction();

sesija.save(knjiga);

sesija.getTransaction().commit();

}

}

Page 95: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 95

Testiranje trajnosti podataka

Postoje dva razlicita nacina na koja je moguce testirati trajnost podataka: prvije pokretanjem SQL upita na bazi podataka, a drugi koriscenjem testnog kli-jenta. Drugi pomenuti nacin je moguce implementirati dodavanjem jos jednogmetoda u okviru klijenta (nazovimo ga nadjiKnjigu). Ovaj metod ce koristitimetod load klase Session da bi izdvojio odgovarajuci red iz baze podataka.

public class OsnovniMenadzerKnjiga{

...

private void nadjiKnjigu(int id_knjige) {

Session sesija = fabrikaSesija.getCurrentSession();

sesija.beginTransaction();

Knjiga knjiga = (Knjiga)sesija.load(Knjiga.class, id_knjige);

System.out.println("Knjiga:" + knjiga);

sesija.getTransaction().commit();

}

}

Metod load izdvaja odgovarajuci objekat klase Knjiga za dati jedinstveniidentifikator koji se prosleduje. Ovo funkcionise tako sto Hibernate u poza-dini pokrece naredbu SELECT u ove svrhe.

Ukoliko zelimo da izdvojimo sve knjige iz tabele, potrebno je kreirati ob-jekat Query sa jednostavnim tekstom upita “from Knjige” i izvrsiti ga. Pri-menom metoda list na upit (koji je kreiran naredbom sesija.createQuery)dobija se lista knjiga na sledeci nacin:

public class OsnovniMenadzerKnjiga{

// izdvajamo sve knjige

private void nadjiSve() {

Session sesija = fabrikaSesija.getCurrentSession();

sesija.beginTransaction();

List<Knjiga> knjige = sesija.createQuery("from Knjige").list();

sesija.getTransaction().commit();

System.out.println("Sve knjige:" + knjige);

}

...

}

Transakcije

Postoje dva pristupa radu sa transakcijama:

• CMT transakcije (engl. Container Managed Transactions) kod kojih kon-tejner moze da kreira i upravlja radom nase aplikacije u njegovim transak-cijama,

• JDBC transakcije kod kojih mi mozemo da upravljamo mehanizmomtransakcija.

Page 96: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

96GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

U prvom slucaju nema potrebe da brinemo o semantici transakcija kao sto jepotvrdivanje i ponistavanje transakcija – o ovome se stara kontejner.

U drugom slucaju, potrebno je kodirati pocetak transakcije i njen uspesanzavrsetak (commit) ili neuspesan zavrsetak (rollback). Jedan moguci scenariobio bi sledeci:

private void sacuvajKnjigu() {

Transaction tr = null;

try {

// kreiramo instancu transakcije

tr = sesija.beginTransaction();

// zapocinjemo zadatak kreiranja i cuvanja instance

Knjiga knjiga = kreirajKnjigu();

sesija.save(knjiga);

// uspesan kraj

tr.commit();

} catch (HibernateException he) {

// imamo problem, ponistavamo transakciju

if (tr!=null)

tr.rollback();

throw he;

} finally{

// zatvaramo transakciju

sesija.close();

}

}

Zapocinjemo transakciju pozivom metoda sesija.beginTransaction(),koji kreira novi objekat transakcije i vraca referencu na njega. Ona je povezanasa sesijom i otvorena sve dok transakcija ne potvrdi svoje izmene ili budeponistena. Nakon toga izvodimo zahtevani zadatak unutar transakcije, a za-tim zahtevamo potvrdu ove transakcije. U ovom stadijumu se entiteti tra-jno cuvaju u bazi podataka. Ukoliko tokom procesa pamcenja ovih podatakadode do neke greske, bice izbacen HibernateException izuzetak. Potrebno jetaj izuzetak uhvatiti i ponistiti transakciju. Moguce je izbaciti dodatne izuzetkenazad klijentu u informativne shrhe ili u svrhe debagovanja.

Anotacije – detaljnije

Pristup u kome se koriste XML datoteke za zadavanje konfiguracije i preslika-vanja ima i prednosti i mane. Prednost bi bila njihova jednostavnost i citljivost,ali ih karakterise i opsirnost, kao i to da nema provere tipova. Anotacije su,sa druge strane, prilicno koncizne i omogucavaju provere u vreme kompi-lacije. Anotacije predstavljaju direktno “ukrasavanje” klase metapodacima,stoga omogucavaju efikasno upravljanje entitetima. U ovom poglavlju cemose detaljno pozabaviti anotacijama.

U nastavku je dat jednostavan primer trajne klase Zaposleni koja je defin-isana bez koriscenja anotacija:

public class Zaposleni {

Page 97: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 97

private int id = 0;

private String ime = null;

...

}

Da bismo je ucinili trajnom koriscenjem anotacija, potrebno je definisati jekao Entity:

@Entity

public class Zaposleni {

private int id = 0;

private String ime = null;

...

}

Naredni korak jeste definisanje identifikatora – to postizemo dodavanjemanotacije @Id. U ovom primeru, primarnom kljucu odgovara promenljiva id

te njoj dodajemo ovu anotaciju:

@Entity

public class Zaposleni {

@Id

private int id = 0;

private String ime = null;

public int getId(){

return id;

}

}

Na ovaj nacin Hibernate preslikava polje id tabele Zaposleni u promenljivuid klase Zaposleni. Napomenimo i to da je moguce ne anotirati promenljivevec odgovarajuce get metode. Ne postoji neko strogo pravilo kada se sta radi,vec imamo izbor i mozemo raditi kako nam je zgodnije. Napomenimo i to danekada u okviru baza podataka nije dozvoljeno koristiti polje id jer je to rez-ervisana rec, pa u toj situaciji treba promeniti ime u npr. id zaposlenog. Uovoj situaciji imena polja objekta i odgovarajuce kolone ne bi bila ista, stogamoramo eksplicitno da zadamo ime kolone koriscenjem dodatne anotacije@Column i zadavanjem atributa name. Svaka anotacija ima definisan svoj skupatributa koji je moguce koristiti.

@Entity

public class Zaposleni{

@Id

@Column(name = "id_zaposlenog")

private int id = 0;

...

Ovu anotiranu datoteku mozemo ukljuciti programski na sledeci nacin:

Configuration konf = new Configuration()

.configure("annotacije/hibernate.cfg.xml")

.addAnnotatedClass(Zaposleni.class);

Page 98: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

98GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Ukoliko se ime tabele razlikuje od imena klase potrebno je dodati anotaciju@Table. U slucaju da se tabela ne zove Zaposleni vec Tabela zaposleni do-dali bismo narednu anotaciju:

@Entity

@Table(name = "Tabela_zaposleni")

public class Zaposleni{

...

}

Slicno, kao sto smo vec videli u slucaju identifikatora id, ako se ime promenljiverazlikuje od imena kolone potrebno je dodati anotaciju @Column:

@Entity

@Table(name = "Tabela_zaposleni")

public class Zaposleni{

...

@Column(name = "ime_zaposlenog")

private int ime = 0;

}

Moguce je postaviti i neka dodatna svojstva koloni koriscenjem atributaanotacije @Column. Na primer, ako kolona ne moze da sadrzi NULL vred-nost, treba postaviti nullable = false. Ili ako se kolona treba generisati saogranicenjem jedinstvenosti treba postaviti unique = true. Na primer:

@Entity

@Table(name = "Tabela_zaposleni")

public class Zaposleni{

@Id

@Column(name="id_zaposlenog", nullable = false, unique = true)

private int zaposleniId = 0;

...

Hibernate podrzava razlicite nacine generisanja identifikatora, kao sto smovideli i u XML preslikavanjima. U prethodnom primeru strategija nije bila za-data sto podrazumeva AUTO strategiju, cime se oslanjamo na bazu podataka ugenerisanju kljuceva. Razlicite strategije se mogu zadati koriscenjem anotacije@GeneratedValue za identifikator, koja podrzava dva atributa: strategy igenerator. Atribut strategy ukazuje na tip generisanja identifikatora, a atributgenerator na metod generisanja identifikatora. Na primer:

@Entity(name = "Tabela_zaposleni")

public class Zaposleni {

@Id

@Column(name="ID")

@GeneratedValue(strategy = GenerationType.IDENTITY)

private int zaposleniId =0;

...

}

Page 99: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 99

Strategija moze imati jednu od narednih vrednosti:

• GeneratorType.AUTO

• GeneratorType.IDENTITY

• GeneratorType.SEQUENCE

• GeneratorType.TABLE

Ne postoji anotacija koja je odgovarajuca strategiji assigned u XML defini-cijama preslikavanja. Ukoliko zelimo da se u aplikaciji postavljaju vrednostijedinstvenog identifikatora, samo ne treba navesti anotaciju @GeneratedValue

uz anotaciju @Id.

Slozeni identifikatori

Ne vazi uvek da jedna kolona na jedinstven nacin identifikuje red tabele.Nekada se kombinacija kolona uzima za primarni kljuc tabele i takav kljucnazivamo slozeni kljuc. U situaciji kada tabela ima slozeni kljuc identifikatormoramo zadati na drugaciji nacin.

Razmotrimo naredni primer: tabela Kurs ima slozeni primarni kljuc koji sesastoji od dva atributa profesor i naziv. U tom slucaju potrebno je definisatiklasu KursPK koja sadrzi dve promenljive: profesor i naziv.

@Embeddable

public class KursPK implements Serializable{

private String profesor = null;

private String naziv = null;

// Podrazumevani konstruktor

public KursPK() {

}

...

}

Ova klasa mora biti oznacena anotacijom @Embeddable, potrebno je da im-plementira interfejs Serializable i da ima definisan podrazumevani kon-struktor. Takode, neophodno je da ima implementirane metode hashCode iequals koji pomazu da Hibernate utvrdi jedinstvenost.

Naredni korak jeste da se ova klasa umetne u promenljivu id nase trajneklase. Ovo radimo koriscenjem jednostavne @Id anotacije:

@Entity

@Table(name="Kurs_anotacije")

public class Kurs {

@Id

private KursPK id = null;

private int ukupnoStudenata = 0;

private int registrovanihStudenata = 0;

public KursPK getId() {

return id;

Page 100: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

100GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

}

public void setId(KursPK id) {

this.id = id;

}

...

}

Mozemo pokrenuti test i videti na koji nacin se slozeni kljuc formira utabeli:

private void sacuvaj() {

...

Kurs kurs = new Kurs();

KursPK kursPk = new KursPK();

kursPk.setNaziv("Racunarstvo i informatika");

kursPk.setProfesor("Prof. Petar Petrovic");

kurs.setId(kursPk);

kurs.setUkupnoStudenata(20);

kurs.setRegistrovanihStudenata(12);

sesija.save(kurs);

...

}

Trajno cuvanje kolekcija

U kontekstu Java programiranja, rad sa kolekcijama je neizbezan. Hibernatepodrzava Java kolekcije kao sto su: List, Set, Array, Map,. . .

U Javi postoje naredni interfejsi kolekcija:

• java.util.Collection (koji je roditelj svih interfejsa kolekcija osim mapa),

• java.util.List (za strukture podataka koje odgovaraju listama),

• java.util.Set (za strukture podataka koje odgovaraju skupovima),

• java.util.Map (za strukture podataka tipa preslikavanje kljuc/vrednost),. . .

Interfejs List je implementiran tako da cuva uredenu listu elemenata. Mikoristimo njegove konkretne implementacije kao sto su ArrayList ili LinkedList,ali za potrebe razvoja Hibernate aplikacije listu je potrebno dizajnirati tako daprati interfejs List, a ne njegovu konkretnu implementaciju. Dakle, potrebnoje da uvek koristimo interfejse prilikom definisanja promenljivih koje odgo-varaju kolekcijama i umesto:

ArrayList<String> knjige = new ArrayList<String>();

iskoristiti:

List<String> knjige = new ArrayList<String>();

Page 101: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 101

Trajno cuvanje liste

Liste predstavljaju jednostavnu strukturu podataka za cuvanje objekata u ure-denom poretku. One, takode, cuvaju informaciju o poziciji elementa, posred-stvom indeksa. Element mozemo umetnuti na proizvoljno mesto u listi, amozemo i izdvojiti proizvoljan element iz liste na osnovu njegovog indeksa.Na primer, pretpostavimo da smo trajno sacuvali listu proizvodaca automo-bila (Mercedes, Opel, Audi,...) koriscenjem Java programa. Ocekujemo daizdvojimo iz tabele podatke o automobilima u onom poretku u kom su biliumetani (a to naravno ne mora da odgovara redosledu u kome su redovi za-pamceni u tabeli). Dakle, prilikom pokretanja upita lista.get(n), ocekujemoda bude vracen n-ti element liste. Da bi ovaj zahtev bio zadovoljen, Hibernateodrzava jos jednu tabelu sa indeksima automobila. Stoga, kada se automobiliizdvoje iz glavne tabele, izdvaja se i indeksirani poredak elemenata iz dodatnetabele. Nakon toga se elementi medusobno povezuju i preslikavaju da bi seodredio poredak i u skladu sa tim klijentu dao uredeni odgovor.

Razmotrimo primer salona automobila koji raspolaze odredenim brojemautomobila koje musterije mogu da razgledaju i potencijalno kupe. Automo-bile cemo modelovati koriscenjem interfejsa java.util.List na sledeci nacin:

public class Salon {

private int id = 0;

private String menadzer = null;

private String lokacija = null;

private List<Automobil> automobili = null;

...

// set i get metode

}

public class Automobil {

private int id;

private String naziv = null;

private String boja = null;

...

// set i get metode

}

Obratimo paznju da klasa Salon sadrzi listu automobila. Definicije preslika-vanja ove dve klase na odgovarajuce tabele bile bi oblika:

<hibernate-mapping>

<!-- Definicije preslikavanja klase Salon -->

<class name="Salon" table="Salon_list">

<id name="id" column="ID_salona">

<generator class="native"/>

</id>

...

<list name="automobili" cascade="all"

table="Automobil_list">

<key column="ID_salona"/>

Page 102: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

102GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

<index column="automobil_index"/>

<one-to-many class="Automobil"/>

</list>

</class>

<!-- Definicije preslikavanja klase Automobil -->

<class name="Automobil" table="Automobil_list">

<id name="id" column="ID_automobila">

<generator class="native"/>

</id>

<property name="naziv" column="naziv"/>

<property name="boja" column="boja"/>

</class>

</hibernate-mapping>

Primetimo da smo koristili element list u prethodnom fragmentu koda.Ovaj element definise preslikavanje automobila deklarisanih u objektu Salon

na tabelu.Glavna tabela, Salon list bice kreirana i popunjena kao sto je i ocekivano.

Medutim, tabela Automobil list je dodatna tabela koja se kreira u hodu.Pored svojstava ID automobila, naziv i boja koja postoje u tabeli Automobil list

i koja su direktno deklarisana na samom objektu, Hibernate pravi jos dvekolone. Jedna od njih je strani kljuc ID salona dok je druga automobil index

koja treba da sadrzi indekse liste i koja se zadaje koriscenjem etikete index

(sva preslikavanja kolekcija, osim Set i Bag zahtevaju kolonu indeksa u tabelikolekcije i to je kolona koja se preslikava u indeks niza, indeks liste ili kljucmape). Kolona automobil index se popunjava pozicijom elementa liste i ko-risti se za kasniju rekonstrukciju elemenata liste na originalnim pozicijama.Prilikom izdvajanja automobila u vreme izvrsavanja Hibernate preureduje re-dove prema njihovom indeksu koji se nalazi u koloni automobil index.

Atribut liste cascade="all" omogucava da se prilikom trajnog cuvanjaobjekta automatski pamte i svi njemu pridruzeni objekti (te se pamcenjem po-dataka o salonu automobila, pamte i podaci o automobilima u odgovarajucojtabeli).

Pokrenimo jednostavnog klijenta zarad testiranja funkcionalnosti trajnogcuvanja liste:

private void sacuvajListu() {

// pravimo objekat salon

Salon salon = new Salon();

salon.setLokacija("Tosin bunar, Beograd");

salon.setMenadzer("Petar Petrovic");

// pravimo listu automobila

List<Automobil> automobili = new ArrayList<Automobil>();

automobili.add(new Automobil("Tojota", "Plava"));

automobili.add(new Automobil("Tojota", "Plava"));

automobili.add(new Automobil("Opel", "Bela"));

automobili.add(new Automobil("BMW", "Crna"));

Page 103: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 103

automobili.add(new Automobil("Mercedes", "Srebrna"));

...

// povezimo automobile sa salonom

salon.setAutomobili(automobili);

// pamtimo podatke o salonu

sesija.save(salon);

}

Prilikom pokretanja testa za izdvajanje rezultata, stampa se naredni izlaz(primetimo duplirani Tojota automobil u izlazu):

Salon{id=6, menadzer=Petar Petrovic, lokacija=Tosin bunar, Beograd,

automobili=[Automobil{id=15, naziv=Tojota, boja=Plava},

Automobil{id=16, naziv=Tojota, boja=Plava},

Automobil{id=17, naziv=Opel, boja=Bela},

Automobil{id=18, naziv=BMW, boja=Crna},

Automobil{id=19, naziv=Mercedes, boja=Srebrna}]}

Kao sto se moze videti, Hibernate uzima u obzir redosled umetanja automo-bila u listu.

Trajno cuvanje skupova

java.util.Set predstavlja neuredenu strukturu podataka u kojoj nije dozvol-jeno pojavljivanje duplikata. Izmenimo prethodni primer tako da je kolekcijaautomobila koja pripada salonu automobila modelovana kao skup. KoristimoHashSet za konkretnu implementaciju Set interfejsa.

public class Salon {

private int id = 0;

private String menadzer = null;

private String lokacija = null;

// automobili su predstavljeni kao skupovi

private Set<Automobil> automobili = null;

// get i set metode

...

}

U ovom slucaju preslikavanje skupa vrsi se koriscenjem etikete set:

<hibernate-mapping>

<class name="Salon" table="Salon_skup">

<id name="id" column="ID_salona">

<generator class="native"/>

</id>

...

<set name="automobili" cascade="all"

Page 104: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

104GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

table="Automobil_skup">

<key column="ID_salona"/>

<one-to-many class="Automobil"/>

</set>

</class>

<class name="Automobil" table="Automobil_skup">

<id name="id" column="ID_automobila">

<generator class="native"/>

</id>

<property name="naziv" column="naziv"/>

<property name="boja" column="boja"/>

</class>

</hibernate-mapping>

Instanca klase Salon se preslikava u tabelu Salon skup, dok se promenljivaautomobili koja je predstavljena skupovnom kolekcijom preslikava u tabeluAutomobil skup. Kljucno je prisustvo stranog kljuca u tabeli Automobil skup.Element <key> oznacava kolonu tabele koja sadrzi strani kljuc. Hibernateautomatski dodaje ovaj strani kljuc tabeli Automobil skup. Stoga ce tabelaAutomobil skup, koju Hibernate kreira i njome upravlja, imati dodatni stranikljuc ID salona kojim se povezuju dve tabele.

Mozemo kreirati klijenta koji ce nam sluziti za testiranje:

private void sacuvajSkup() {

// Kreiramo i popunjavamo salon

Salon salon = new Salon();

salon.setLokacija("Tosin bunar, Beograd");

salon.setMenadzer("Petar Petrovic");

// Kreiramo i popunjavamo skup automobila

Set<Automobil> automobili = new HashSet<Automobil>();

automobili.add(new Automobil("Tojota", "Plava"));

automobili.add(new Automobil("Opel", "Bela"));

automobili.add(new Automobil("BMW", "Crna"));

automobili.add(new Automobil("BMW", "Crna"));

...

// povezimo automobile sa salonom

salon.setAutomobili(automobili);

// pamtimo podatke o salonu

sesija.save(salon);

}

U prikazanom primeru kreirali smo objekat tipa Salon i dodali mu tri au-tomobila. Pokusaj dodavanja istog automobila ne uspeva jer se utvrduje dasu ova dva automobila identicna i duplikat se izbacuje.

Prilikom rada sa skupovima moramo zadovoljiti zahtev jednakosti: mo-ramo kreirati metode equals i hashCode u klasi Automobil. Kao sto znamo

Page 105: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 105

skup ne moze da sadrzi dva ista elementa i ova dva metoda pomazu da budezadovoljen ovaj zahtev.

Metod za izdvajanje skupa bi izdvojio trajno sacuvani skup iz baze po-dataka na sledeci nacin:

Salon{id=7, menadzer=Petar Petrovic, lokacija=Tosin bunar, Beograd,

automobili=[Automobil{id=27, naziv=Tojota, boja=Plava},

Automobil{id=26, naziv=Opel, boja=Bela},

Automobil{id=28, naziv=BMW, boja=Crna}]}

Mozemo primetiti da BMW automobil nije izlistan dva puta, iako smo ga dvaputa dodali u skup.

Trajno cuvanje mapa

Kada postoji zahtev za predstavljanjem parova naziv/vrednost, prvi izbor bitrebalo da budu mape. Struktura podataka Map je kao recnik u kome pos-toji kljuc (rec) i odgovarajuca vrednost (znacenje). Razmotrimo dalje primersalona automobila i dodajmo mu mogucnost da on sadrzi potencijalne rezer-vacije musterija za testnu voznju automobila. Ovu funkcionalnost mozemo nanajbolji nacin implementirati koriscenjem strukture podataka mapa, povezi-vanjem musterija sa rezervacijama automobila:

public class Salon {

private int id = 0;

private String menadzer = null;

private String lokacija = null;

private Map<String, Automobil> automobili = null;

// get i set metode

}

Svaki automobil je rezervisan od strane neke musterije, i svi automobili pri-padaju salonu automobila. Musterija je ovde predstavljena stringom koji odgo-vara imenu, te ovaj tip zahteva mozemo implementirati koriscenjem tipa po-dataka Map<String,Automobil>. Kljucna stvar jeste kako zadati preslikavanje:

<hibernate-mapping>

<class name="Salon" table="Salon_map">

<id column="ID_salona" name="id">

<generator class="native"/>

</id>

<property column="menadzer" name="menadzer"/>

...

<map name="automobili" cascade="all" table="Automobil_map">

<key column="ID_salona"/>

<map-key column="ime_musterije" type="string" />

<one-to-many class="Automobil"/>

</map>

</class>

Page 106: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

106GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

<class name="Automobil" table="Automobil_map">

<id column="ID_automobila" name="id">

<generator class="native"/>

</id>

<property name="naziv" column="naziv" />

<property name="boja" column="boja" />

</class>

</hibernate-mapping>

Kao sto je i ocekivano, promenljiva automobili salona automobila je pred-stavljena elementom map koji se odnosi na tabelu Automobil map iz definicijepreslikavanja. Element map definise strani kljuc (u ovom slucaju ID salona).Atribut map-key definise kljuc mape – u ovom slucaju musteriju.

Preslikavanje klase Automobil je pravolinijsko. Naglasimo i to da Hiber-nate dodaje jos nekoliko kolona tabeli Automobil map: ID salona i ime musterije,pored postojecih kolona naziv i boja. Sada mozemo testirati preslikavanjekoriscenjem narednog fragmenta koda:

private void sacuvajMapu() {

Salon salon = new Salon();

salon.setLokacija("Tosin bunar, Beograd");

salon.setMenadzer("Petar Petrovic");

Map<String, Automobil> automobili = new HashMap<String, Automobil>();

automobili.put("Marko", new Automobil("Tojota", "Zelena"));

automobili.put("Milos", new Automobil("Opel", "Bela"));

automobili.put("Milan", new Automobil("BMW", "Crna"));

salon.setAutomobili(automobili);

// pamtimo podatke o salonu

sesija.save(salon);

}

Ovim smo kreirali mapu sa imenom musterije i automobilima za testnuvoznju. Nakon toga smo ih dodali salonu automobila. Kao sto mozemo videtiu strukturi podataka Map imamo sasvim novi automobil za svaku musteriju.

Trajno cuvanje kolekcija koriscenjem anotacija

Videli smo kako sacuvati kolekcije koriscenjem XML datoteka za zadavanjepreslikavanja. Alternativno, moguce je u ove svrhe koristiti i anotacije. Na-jpre je neophodno dodati odgovarajuce anotacije entitetima u primeru salonaautomobila. Postoje dva metoda pripreme koda za anotacije koji sadrzi kolek-cije:

• koriscenjem stranog kljuca,

• koriscenjem spojne tabele.

Page 107: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 107

Pogledajmo najpre metod pripreme zasnovan na koriscenju stranog kljuca.Svaki salon sadrzi potencijalno vise automobila, sto predstavlja vezu tipa “jedanprema vise”. Dakle, entitet Salon se sastoji od kolekcije automobila. Automo-bili, sa druge strane, pripadaju salonu; stoga su modelovani da imaju odnosstranog kljuca ka salonu.

Razmotrimo najpre entitet Salon:

@Entity(name="Salon_list_an")

@Table(name="Salon_list_an")

public class Salon {

@Id

@Column(name="ID_salona")

@GeneratedValue(strategy=GenerationType.AUTO)

private int id = 0;

@OneToMany

@JoinColumn(name="ID_salona")

@Cascade(CascadeType.ALL)

private List<Automobil> automobili = null;

// ostala svojstva

private String menadzer = null;

private String lokacija = null;

}

Klasa Salon je deklarisana kao trajni entitet, koji se preslikava u tabelu sanazivom Salon_list_an. Identifikator je definisan koriscenjem automatskestrategije, sto podrazumeva da se identifikator postavlja jednom od funkcijabaze podataka, kao sto su auto increment ili identity.

Osvrnimo se na vazno svojstvo salona: kolekcija automobila je predstavl-jena promenljivom automobili i ona je kolekcijskog tipa lista: java.util.List.Ova promenljiva je oznacena anotacijom @OneToMany jer svaki salon sadrzivise automobila, a svaki automobil pripada salonu. Ranije smo naucili dakolekcija automobila ima svoju tabelu sa stranim kljucem koji referise na pri-marni kljuc tabele Salon (u ovom slucaju to je ID salona). Da bi Hibernateznao za ovu zavisnost, deklarisemo promenljivu automobili zajedno sa an-otacijom @JoinColumn koja definise strani kljuc. Moramo proslediti nazivkolone ID salona da bismo pokupili listu automobila iz tabele automobila.Anotacija @Cascade omogucava da Hibernate trajno sacuva kolekcije povezanesa glavnom instancom.

Za razliku od entiteta Salon, entitet Automobil je jednostavan i pravolini-jski:

@Entity(name="Automobil_list_an")

@Table(name="Automobil_list_an")

public class Automobil {

@Id

@GeneratedValue(strategy= GenerationType.AUTO)

@Column(name="ID_automobila")

private int id;

Page 108: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

108GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

private String naziv = null;

private String boja = null;

...

}

Slede i skriptovi za kreiranje tabela Salon list an i Automobil list an.

CREATE TABLE Salon_list_an (

ID_salona integer NOT NULL,

lokacija varchar(255) DEFAULT NULL,

menadzer varchar(255) DEFAULT NULL,

PRIMARY KEY (ID_salona)

)

CREATE TABLE Automobil_list_an (

ID_automobila integer NOT NULL,

boja varchar(255) DEFAULT NULL,

naziv varchar(255) DEFAULT NULL,

ID_salona integer DEFAULT NULL,

PRIMARY KEY (ID_automobila),

FOREIGN KEY (ID_salona) REFERENCES Salon_list_an (ID_salona)

)

Tabela automobila ima svoj primarni kljuc ID automobila plus strani kljucID salona koji referise na glavnu tabelu.

Podsetimo se da bi sad bilo potrebno dodati anotirane klase u konfigu-raciju, kao u sledecem slucaju:

Configuration konf = new Configuration()

.configure("kolekcije/hibernate.cfg.xml")

.addAnnotatedClass(Salon.class)

.addAnnotatedClass(Automobil.class);

Sam mehanizam trajnog cuvanja kolekcije se ne bi ni u cemu razlikovaood prethodnog slucaja kada smo cuvali liste.

Sada kada smo videli kako da sacuvamo kolekcije koriscenjem stranogkljuca, pogledajmo i drugi metod: koriscenjem spojne tabele. Prilikom koriscenjaove strategije, mora da postoji (spojna) tabela preslikavanja koja sadrzi pri-marne kljuceve obe tabele.

U primeru salona automobila potrebno je napraviti neke izmene u anoti-ranju:

@Entity(name="Salon_set_an_spojnatabela")

@Table(name="Salon_set_an_spojnatabela")

public class Salon {

@Id

@Column(name="ID_salona")

@GeneratedValue(strategy=GenerationType.AUTO)

private int id = 0;

private String menadzer = null;

private String lokacija = null;

Page 109: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 109

@OneToMany

@JoinTable

(name="Salon_automobil_set_an_spojnatabela",

joinColumns = @JoinColumn(name="ID_salona")

)

@Cascade(CascadeType.ALL)

private Set<Automobil> automobili = null;

...

}

Anotacija @JoinTable u prethodnom fragmentu ukazuje da ce biti kreiranaspojna tabela (u ovom slucaju tabela Salon automobil set an spojnatabela).Primetimo, takode, da se automobili izdvajaju na osnovu kolone ID salona.Spojna tabela koja se kreira ima sledecu formu:

CREATE TABLE salon_automobil_set_an_spojnatabela (

ID_salona integer NOT NULL,

ID_automobila integer NOT NULL,

PRIMARY KEY (ID_salona,ID_automobila),

FOREIGN KEY (ID_salona) REFERENCES salon_set_an_spojnatabela (ID_salona),

FOREIGN KEY (ID_automobila) REFERENCES automobil_set_an_spojnatabela (ID_automobila)

)

Primarni kljuc ove tabele cini kombinacija ID salona i ID automobila.

Asocijacije (veze)

Da bismo koristili Hibernate, neophodno je najpre razumeti veze izmedu Javaobjekata. U Javi se ovakve veze jednostavno predstavljaju: koristimo atributeklase (promenljive) u te svrhe. Pogledajmo jedan jednostavan primer:

public class Automobil {

private int id;

// Automobil ima motor

private Motor motor;

...

}

public class Motor {

private int id = 0;

private String proizvodjac = null;

...

}

Iz ovog koda mozemo zakljuciti da je klasa Automobil povezana sa klasomMotor.

Odnosima zovemo veze izmedu tabela relacione baze podataka. Odnosse najcesce realizuje koriscenjem mehanizama primarnih i stranih kljuceva.Veze karakterisu dva svojstva: visestrukost i usmerenost. Termin visestrukostse odnosi na to koliki broj konkretnih objekata je povezan sa koliko ciljnih

Page 110: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

110GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

objekata. U prethodnom primeru mogli bismo zakljuciti da svaki automobilima motor, a svaki motor pripada jednom automobilu. Ovo je tip veze “jedanprema jedan”. Pored ovog postoje jos tipovi: “vise prema vise” i “jedan premavise”.

Drugo bitno svojstvo je usmerenost, odnosno smer ka kome tezi asocijacija.U primeru automobila i motora, ispitivanjem atributa automobila mozemoda vidimo koji je motor u pitanju, ali nazalost na osnovu motora ne mozemodobiti detalje o automobilu. Asocijacije mogu biti jednosmerne ili dvosmerne.Veza izmedu automobila i motora je jednosmerna.

S druge strane, ako se mozemo kretati od izvornog do ciljnog objektai u suprotnom smeru, za vezu se kaze da je dvosmerna. U slucaju klasaAutomobil i Salon, vazi da mozemo odrediti vlasnika na osnovu objekta klaseAutomobil, kao i vlasnikov automobil za dati objekat Vlasnik.

public class Vlasnik {

private int id = 0;

// mogli bismo imati listu automobila koje vlasnik poseduje

// ali jednostavnosti radi neka bude jedan automobil

private Automobil automobil = null;

...

}

public class Automobil {

private int id = 0;

private Vlasnik vlasnik = null;

...

}

Na ovaj nacin obezbedujemo referencu na objekat Automobil u klasi Vlasniki referencu na objekat Vlasnik u klasi Automobil. Ovo je primer veze tipa“jedan prema jedan”.

Vezu tipa “vise prema vise” mozemo uociti u odnosu studenta i kursa.Naime, mozemo za datog studenta (za dati objekat klase Student) utvrditikoje kurseve on pohada, a takode, na osnovu objekta klase Kurs mozemo za-kljuciti koji studenti pohadaju taj kurs.

public class Student {

private int id = 0;

private List<Kurs> kursevi = null;

...

}

public class Kurs {

private int id = 0;

private List<Student> studenti = null;

...

}

Na ovaj nacin se izrazava veza tipa vise prema vise.

Page 111: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 111

Veza tipa “jedan prema jedan”

Postoje dva nacina za uspostavljanje veze tipa “jedan prema jedan”:

• koriscenjem deljenog primarnog kljuca,

• koriscenjem stranog kljuca.

U objektnom modelu ova razlika nije ocigledna, ali u relacionom modelu jeste.Ilustrovacemo ovu vezu na primeru klasa Automobil i Motor:

public class Automobil {

private int id;

private String naziv;

private String boja;

private Motor motor;

...

}

public class Motor {

private int id = 0;

private String proizvodjac = null;

private String model = null;

private Automobil automobil = null;

}

Razmotrimo kako zadati sheme tabela za uspostavljanje veze “jedan premajedan” koriscenjem deljenog primarnog kljuca.

CREATE TABLE Automobil (

ID_automobila integer NOT NULL,

naziv varchar(20) DEFAULT NULL,

boja varchar(20) DEFAULT NULL,

PRIMARY KEY (ID_automobila))

CREATE TABLE Motor (

ID_automobila integer NOT NULL,

proizvodjac varchar(20) DEFAULT NULL,

model varchar(20) DEFAULT NULL,

PRIMARY KEY (ID_automobila),

FOREIGN KEY (ID_automobila) REFERENCES Automobil (ID_automobila))

U ovom pristupu treba obratiti paznju da je primarni kljuc tabele Motor

kolona ID automobila. Takode, postoji ogranicenje stranog kljuca na tabeluAutomobil. Stoga motor mora uvek da bude kreiran sa istim identifikatoromkao i automobil, te kazemo da ove dve tabele dele primarni kljuc.

Razmotrimo sada kako izgleda preslikavanje za vezu tipa “jedan premajedan”, tj. sadrzaj datoteke Automobil.hbm.xml:

<hibernate-mapping>

<class name="Automobil" table="Automobil">

<id name="id" column="ID_automobila">

Page 112: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

112GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

<generator class="assigned"/>

</id>

<property name="naziv" column="naziv"/>

<property name="boja" column="boja"/>

<one-to-one name="motor" class="Motor" cascade="all"/>

</class>

</hibernate-mapping>

Ono sto je novo jeste etiketa <one-to-one> kojom se postavlja svojstvomotor. Ova anotacija oznacava da:

• instanca Automobil ima svojstvo koje se zove motor

• Automobil i Motor su u odnosu jedan prema jedan

• Motor se postavlja koriscenjem vrednosti iz tabele Motor (koja se pakpreslikava u objekat Motor)

Preslikavanje klase Motor je za nijansu komplikovanije:

<hibernate-mapping">

<class name="Motor" table="Motor">

<id name="id" column="ID_automobila" >

<generator class="foreign">

<param name="property">automobil</param>

</generator>

</id>

<one-to-one name="automobil" class="Automobil"

constrained="true"/>

...

</class>

</hibernate-mapping>

Znamo da je primarni kljuc (id) motora isti kao id automobila. Ovu cinjenicutreba na neki nacin pomenuti u samom preslikavanju da bi Hibernate znaokako da se postavi u ovoj situaciji. Postoji specijalna klasa generatora foreign

u ove svrhe. Ovaj generator proverava svojstvo sa imenom automobil i biraid iz te reference.

Postoji jos jedan novi atribut koji se koristi u elementu:one-to-one: constrained="true"

Jednostavno govoreci, ovo oznacava da primarni kljuc tabele Motor ima ogra-nicenje stranog kljuca, koje se moze izvesti iz primarnog kljuca tabele Automobil.

Aplikaciju mozemo testirati koriscenjem naredne testne klase:

public class JedanPremaJedanTest {

...

private void sacuvaj() {

...

// Kreiramo instancu Automobil, postavljamo id i ostala svojstva

Automobil automobil = new Automobil();

Page 113: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 113

// Setimo se, koristimo generator aplikacije za id

automobil.setId(1);

automobil.setNaziv("Kadilak Sedan");

automobil.setBoja("Bela");

// Kreiramo instancu Motor i postavljamo svojstva

// Paznja: ne postavljamo id

Motor motor = new Motor();

motor.setProizvodjac("Sedan");

motor.setModel("DTS");

// Sada ih povezujemo zajedno

automobil.setMotor(motor);

motor.setAutomobil(automobil);

// Na kraju, trajno pamtimo objekte

sesija.save(automobil);

sesija.save(motor);

...

}

}

Primarni kljuc motora se ne postavlja prilikom pravljenja: to je zato stopozajmljujemo i delimo id iz automobila. U ovom pristupu trajno cuvamoi automobil i motor. Oni su u velikoj meri individualne tabele sa izuzetkomogranicenja primarnog kljuca. U drugom pristupu videcemo kako se objekatklase Motor cuva tako sto se sacuva samo objekat klase Automobil.

Da bismo za modeliranje odnosa “jedan prema jedan” koristili ogranicenjestranog kljuca, potrebno je promeniti definicije tabela i preslikavanja na sledecinacin:

CREATE TABLE Automobil_V2 (

ID_automobila integer NOT NULL,

ID_motora integer NOT NULL,

boja varchar(20) DEFAULT NULL,

naziv varchar(20) DEFAULT NULL,

PRIMARY KEY (ID_automobila),

CONSTRAINT fk_motor_id FOREIGN KEY (ID_motora)

REFERENCES Motor_v2 (ID_motora)

)

CREATE TABLE Motor_V2 (

ID_motora integer NOT NULL,

proizvodjac varchar(20) DEFAULT NULL,

model varchar(20) DEFAULT NULL,

PRIMARY KEY (ID_motora)

)

Definicija tabele Motor V2 je jednostavna: to je normalna tabela sa pri-marnim kljucem ID motora. Primetna razlika je u tabeli Automobil V2: pored

Page 114: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

114GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

svog primarnog kljuca (ID automobila), postoji i strani kljuc ID motora kojipokazuje na tabelu Motor V2.

Preslikavanje klase Motor nije ni u cemu drugacije od dosadasnjeg (definisemoaplikacijsku strategiju za postavljanje id-a objekta):

<hibernate-mapping >

<class name="Motor" table="Motor_V2">

<id name="id" column="ID_motora" >

<generator class="assigned"/>

</id>

...

</class>

</hibernate-mapping>

Preslikavanje klase Automobil bi imalo narednu formu:

<hibernate-mapping>

<class name="Automobil" table="Automobil_V2">

<id name="id" column="ID_automobila" >

<generator class="assigned"/>

</id>

<property name="naziv" column="naziv" />

<property name="boja" column="boja"/>

<!-- stavka unique="true" postavlja ovu vezu tipa

"vise prema jedan" na "jedan prema jedan"

ovo je bitno podesavanje u ovom pristupu -->

<many-to-one name="motor" class="Motor"

column="id_motora"

unique="true"

cascade="all" />

</class>

</hibernate-mapping>

Za modelovanje odnosa “jedan prema jedan” putem ogranicenja stranogkljuca potrebno je iskoristiti <many-to-one> vezu (koja omogucava zadavanjestranih kljuceva), ali se stavkom unique=’true’ postavlja da je odnos “jedanprema jedan”.

Izmenimo klijenta za testiranje:

private void sacuvaj_V2() {

// pravimo motor

Motor m = new Motor();

m.setId(1);

m.setProizvodjac("Sedan");

m.setModel("DTS");

// pravimo automobil

Automobil automobil = new Automobil();

automobil.setId(1);

Page 115: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 115

automobil.setNaziv("Kadilak Sedan");

automobil.setBoja("Bela");

// povezujemo ih zajedno

automobil.setMotor(m);

// sacuvajmo automobil koriscenjem metoda save.

// napomena: motor se automatski cuva zbog

atributa cascade koji je definisan u preslikavanju

sesija.save(automobil);

...

}

Primetimo da se motor ne pamti eksplicitno. Ovo je zato sto kada se autosacuva, njemu pridruzeni objekti (motor u ovom slucaju) se takode pamtezbog atributa cascade="all" definisanog u datoteci preslikavanja.

Ukoliko koristimo anotacije, klase je potrebno anotirati na sledeci nacin:

@Entity

@Table(name="Automobil_1prema1_an")

public class Automobil {

@Id

@Column(name="ID_automobila")

@GeneratedValue(strategy= GenerationType.AUTO)

private int id;

private String naziv = null;

@OneToOne (cascade= CascadeType.ALL)

@JoinColumn(name="ID_motora")

private Motor motor = null;

...

Klasa Automobil je anotirana sa @Entity cime se kvalifikuje da bude trajnosacuvana. Anotacija @Id je deklarisana na polju id koje pokazuje na kolonuID automobila iz tabele. Preslikavanje tipa “jedan prema jedan” se deklarisekoriscenjem anotacije @OneToOne. S obzirom na to daje potrebno spojiti auto-mobil sa tabelom Motor, anotacija @JoinColumn se koristi na koloni ID motora.

Klasa Motor je dosta jednostavnija, treba samo obratiti paznju na anotaciju@OneToOne:

@Entity

@Table(name="Motor_1prema1_an")

public class Motor {

@Id

@Column(name="ID_motora")

@GeneratedValue(strategy= GenerationType.AUTO)

private int id = 0;

@OneToOne(mappedBy="automobil")

Page 116: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

116GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

private Automobil automobil = null;

...

Veza tipa “jedan prema vise”

Odnos izmedu automobila i salona automobila jeste odnos tipa “jedan premavise”: svaki automobil pripada tacno jednom salonu automobila, dok jedansalon automobila sadrzi vise automobila. Pretpostavimo za pocetak da klasaAutomobil nema nikakvu referencu na objekat klase Salon (tj. da je ovaj odnosjednosmeran). Podsetimo se definicija odgovarajucih klasa:

public class Automobil {

private int id;

private String naziv = null;

private String boja = null;

...

// set i get metode

}

public class Salon {

private int id = 0;

private String menadzer = null;

private String lokacija = null;

private Set<Automobil> automobili = null;

...

// set i get metode

}

Pre nego sto razmotrimo kako bi izgledale datoteke preslikavanja, pogleda-jmo skriptove za pravljenje odgovarajucih tabela. Setimo se, tabela Automobilce sadrzati strani kljuc koji odgovara primarnom kljucu tabele Salon:

CREATE TABLE Salon_1premavise (

ID_salona integer NOT NULL,

lokacija varchar(255) DEFAULT NULL,

menadzer varchar(255) DEFAULT NULL,

PRIMARY KEY (ID_salona)

)

CREATE TABLE Automobil_1premavise (

ID_automobila integer NOT NULL,

boja varchar(255) DEFAULT NULL,

naziv varchar(255) DEFAULT NULL,

ID_salona integer DEFAULT NULL,

PRIMARY KEY (ID_automobila),

FOREIGN KEY (ID_salona) REFERENCES Salon_1premavise (ID_salona)

)

Slede odgovarajuce datoteke preslikavanja (definicija preslikavanja za klasuAutomobil je pravolinijska, dok se u definiciji preslikavanja klase Salon vodiracuna o vezi izmedu ove dve klase):

Page 117: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 117

<hibernate-mapping>

<class name="Automobil" table="Automobil_1premavise">

<id name="id" column="ID_automobil">

<generator class="assigned"/>

</id>

<property name="boja" column="boja" />

...

</class>

</hibernate-mapping>

<hibernate-mapping>

<class name="Salon" table="Salon_1premavise">

<id name="id" column="ID_salona" >

<generator class="assigned"/>

</id>

<property name="menadzer" column="menadzer" />

...

<set name="automobili" table="Automobil_1premavise"

cascade="all">

<key column="ID_automobila" not-null="true"/>

<one-to-many class="Automobil"/>

</set>

</class>

</hibernate-mapping>

U definicijama preslikavanja je iskodirano da za svaki salon automobilamozemo izdvojiti skup automobila iz tabele Automobil 1premavise koji jepovezan sa klasom Automobil, na osnovu kljuca ID automobila.

U ovom primeru, obzirom da relacija nije dvosmerna, nismo u mogucnostida na osnovu podataka o automobilu izdvojimo salon kome on pripada. Im-plementiranje dvosmerne relacije zahteva neke male izmene u klasama i pres-likavanjima. Najpre je potrebno dodati referencu na objekat Salon u tabeluAutomobil:

public class Automobil {

private int id;

private String naziv = null;

private String boja = null;

...

private Salon salon = null;

public Salon getSalon(){

return salon;

}

public void setSalon(Salon salon){

this.salon = salon;

}

// ostale set i get metode

}

Naredna izmena bila bi u odgovarajucoj datoteci preslikavanja Automobil.hbm.xml;sada bi i ona sadrzala element preslikavanja tipa “jedan prema vise”:

Page 118: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

118GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

<hibernate-mapping>

<class name="Automobil" table="Automobil_1premavise">

<id name="id" column="ID_automobil">

<generator class="assigned"/>

</id>

<property name="boja" column="boja" />

<many-to-one name="salon" column="ID_salona" class="Salon">

</class>

</hibernate-mapping>

Element <many-to-one> ukazuje na stranu “vise” klase Automobil. Sada,ne samo da mozemo da dobijemo sve automobile jednog salona automobila,vec je moguce dobiti i salon automobila u kome se automobil izlaze, pozivommetoda: automobil.getSalon(). Ovim se uspostavlja dvosmerna veza izmeduautomobila i salona.

Veza tipa “vise prema vise”

Veza tipa “vise prema vise” uspostavlja odnos izmedu dve klase na taj nacinda svaka klasa sadrzi vise instanci druge klase i obratno. U slucaju klasaStudent i Kurs, odnos je tipa “vise prema vise” jer student moze da upise visekurseva, a takode jedan isti kurs moze da upise vise studenata. U Javi se ovajodnos realizuje tako sto obe strane imaju atribut koji je tipa kolekcija objekatadruge klase. U bazama podataka se ovaj odnos najcesce realizuje koriscenjemvezne tabele.

Pretpostavimo da klase Student i Kurs imaju sledeci format:

public class Student {

private int id = 0;

private String ime = null;

private Set<Kurs> kursevi = null;

...

}

public class Kurs {

private int id = 0;

private String naziv = null;

private Set<Student> studenti = null;

...

}

Odgovarajuca preslikavanja bila bi oblika:

<hibernate-mapping>

<class name="Student" table="Student">

...

<set name="kursevi" table="Student_kurs" cascade="all">

<key column="ID_studenta" />

<many-to-many column="ID_kursa" class="Kurs"/>

</set>

</class>

Page 119: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 119

</hibernate-mapping>

<hibernate-mapping>

<class name="Kurs" table="Kurs">

...

<set name="studenti" table="Student_kurs" inverse="true"

cascade="all">

<key column="ID_kursa" />

<many-to-many column="ID_studenta" class="Student"/>

</set>

</class>

</hibernate-mapping>

U Hibernate-u samo jedna strana (klasa) je odgovorna za odrzavanje dvos-merne veze (izmenu vrednosti kolona kojima se uspostavlja veza). Dakle,u okviru dvosmernih veza potrebno je zadati kljucnu rec inverse kojom sezadaje koja strana veze je odgovorna za nju: opcija inverse="true" znacida je ova strana odgovorna za vezu, a opcija inverse="false" da nije. Ovoodgovara opciji mappedBy kod anotacija.

Dodatno, potrebno je napraviti veznu tabelu:

CREATE TABLE Student_kurs (

ID_kursa integer NOT NULL,

ID_studenta integer NOT NULL,

PRIMARY KEY (ID_kursa,ID_studenta),

FOREIGN KEY (ID_kursa) REFERENCES kurs (ID_kursa),

FOREIGN KEY (ID_studenta) REFERENCES student (ID_studenta)

)

Ako koristimo anotacije, potrebno je vezu tipa “vise prema vise” anotiratitako sto se u jednoj od klasa (npr. Student) doda anotacija oblika:

@ManyToMany

@JoinTable

(name="Student_kurs",

joinColumns = @JoinColumn(name="ID_studenta")

)

@Cascade(CascadeType.ALL)

private Set<Kurs> kursevi = null;

a u klasi Kurs svojstvo:

@ManyToMany(mappedBy="kursevi")

private Set<Student> studenti = null;

Slicno vazi i za vezu tipa “jedan prema vise” samo je oznaka anotacije@OneToMany.

Page 120: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

120GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Hibernate Query Language (HQL)

Hibernate Query Language (skraceno HQL) je upitni jezik specijalno dizajni-ran za upite nad Java objektima. To je jednostavan upitni jezik, nalik SQL-u.

SQL se koristi za upite nad relacionim tabelama. Ipak, namera Hibernate-a je bila da se kreira jednostavan jezik za ugodan rad sa objektnim modelom.Pritom on bi trebalo da bude sto vise nalik SQL-u. Na primer, da bismo izd-vojili sve redove tabele Knjige, u SQL-u bismo to uradili upitom SELECT *

FROM Knjige, a u HQL-u bi koristili upit FROM Knjiga. Obzirom da u HQL-u radimo sa objektima, potrebno je obezbediti ime klasnog entiteta kojim jepredstavljena tabela, u ovom slucaju Knjiga je trajni Java entitet koji se pres-likava u tabelu Knjige. Ukoliko izdvajamo sve kolone tabele, nije neophodnonavesti kljucnu rec SELECT. Ipak, moramo je koristiti ako radimo sa jednom ilivise pojedinacnih kolona. U HQL-u se mogu koristiti i sledeci konstrukti izSQL-a: WHERE, ORDER BY, MAX, . . .

U Hibernate okruzenju postoji Query API za rad sa objektno-relacionimupitima. Klasa Query, koja ima jednostavan interfejs, predstavlja centralni deoAPI-a. Ocigledno, prva stvar koja nam je potrebna jeste instanca klase Query.Nju dobijamo pozivom metoda createQuery na tekucem objektu sesije. Jed-nom kada imamo instancu Query, nad njom mozemo koristiti razlicite metodeda bismo dobili zeljeni rezultujuci skup iz baze podataka. Naredni fragmentkoda ilustruje na koji nacin mozemo dobiti instancu Query:

// dobijamo tekucu sesiju

Session sesija = fabrikaSesija.getSesion();

// instanca upita se pravi iz ove sesije

Query upit = sesija.createQuery("from Knjiga");

Dakle, potrebno je pozvati metod createQuery nad objektom sesije i pritom prosledujemo upit koji zelimo da izvrsimo nad bazom podataka. MetodcreateQuery prihvata stringovnu reprezentaciju upita. Hibernate nakon togatransformise ovaj deo HQL stringa u odgovarajuci SQL upit (obzirom da bazepodataka mogu samo da razumeju SQL upite) i izvrsava ga da bi izdvojiosve redove tabele Knjiga. Ovo je slicno koriscenju odgovarajuceg SQL upitaSELECT * FROM Knjige, ali postoji nekoliko suptilinih razlika:

• za razliku od SQL-a, u HQL-u se kljucna rec SELECT ne pise (tj opcionaje) ako izdvajamo celu tabelu

• dok se u SQL naredbama javljaju relacione tabele, HQL koristi naziveklasa. Knjiga je trajni entitet koji predstavlja tabelu Knjige

Izdvajanje svih redova tabele je prilicno pravolinijsko i moze se uraditi nanaredni nacin:

private void izdvojiSveKnjige() {

Query upit = sesija.createQuery("from Knjiga");

List<Knjiga> knjige = upit.list();

for (Knjiga knjiga : knjige) {

System.out.println("Knjiga: " + knjiga);

}

Page 121: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 121

...

}

Dakle, kada dobijemo instancu upita sa ugradenim odgovarajucim HQLupitom, pozivamo metod list da bismo izdvojili sve redove tabele. Iza sceneHibernate transformise sve redove baze podataka u instance Knjiga i izdvajaih koriscenjem kolekcije java.util.List. Obzirom da je ovo standardna Javakolekcija, potrebno je jednostavno iterirati kroz nju da bismo dobili pojed-inacne knjige koriscenjem petlje for prikazane u prethodnom kodu.

Uporedimo ovu operaciju sa odgovarajucim JDBC kodom:

private void izdvojiKnjige() {

List<Knjiga> knjige = new ArrayList<Knjiga>();

Knjiga k = null;

try {

Statement st = getConnection().createStatement();

ResultSet rs = st.executeQuery("SELECT * FROM Knjige");

while (rs.next()) {

k = new Knjiga();

k.setId(rs.getInt("id"));

k.setNaziv(rs.getString("naziv"));

knjige.add(k);

}

} catch (SQLException ex) {

System.err.println(ex.getMessage());

}

}

Najpre pravimo naredbu i izvrsavamo upit nad njom, koji vraca instancuklase ResultSet. Ona se sastoji od redova, ali oni nisu u objektnom formatu,vec u sirovoj formi, te je potrebno proci kroz svaku instancu da bismo izdvojilisvaki pojedinacni red; zatim je iz svakog pojedinacnog reda potrebno izdvojitikolone, bilo prema njihovom imenu ili lokaciji. Iz ovako ekstrahovanih kolonapravimo objekat Knjiga i dodajemo ga kolekciji knjiga. U Hibernate-u smosve ove korake apstrahovali u par linija koda. Sta vise, moze biti i samo jednalinija koda ukoliko vrsimo nadovezivanje metoda:

List<Knjiga> knjige =

sesija.createQuery("from Knjiga").list();

Ukoliko zelimo da izdvojimo samo odredeni broj redova, to je mogucepostici pozivom metoda setMaxResults sa vrednoscu broja redova, na primer:

Query upit = sesija.createQuery("from Knjiga");

upit.setMaxResults(100);

upit.setFirstResult(10);

List<Knjiga> knjige = upit.list();

Metod setMaxResults stavlja do znanja Hibernate-u da smo zaintereso-vani da vidimo samo 100 redova. Druga opcija koju smo postavili na upitjeste pocetna pozicija rezultujuceg skupa. Na primer, prethodni kod izdvaja100 objekata iz tabele, pocev od 10. reda.

Page 122: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

122GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Izdavajanje jedinstvenog reda

Kada znamo da postoji jedan i samo jedan red za dati kriterijum, mozemo ko-ristiti API-jev metod uniqueResult. Pretpostavimo da zelimo da izdvojimoknjigu “Prokleta avlija” pod pretpostavkom da postoji samo jedna ovakva kn-jiga. Ovo bi mogli uraditi narednim upitom:

private void getKnjigaJedinstvena() {

...

Query upit = sesija.createQuery("from Knjiga

where naziv=’Prokleta Avlija’");

Knjiga knjiga = (Knjiga) upit.uniqueResult();

}

Ukoliko ne postoji odgovarajuci red, metod vraca null, a ako postoji viseredova u rezultatu bice izbacen izuzetak.

Imenovani parametri

U prethodnom HQL upitu, hardkodirali smo naziv ‘Prokleta avlija’. Nijedanulazni kriterijum ne bi trebalo hardkodirati jer je potrebno podrzati mogucnostda se ovaj kriterijum moze izmeniti. Stoga bi bilo zgodno parametrizovatiovakve stvari. U HQL-u moguce je postaviti ulazne parametre objekta Query

koriscenjem naredne sintakse:

private void izdvojiKnjigeParametarski(String knjiga) {

...

Query upit = sesija.createQuery(

"from Knjiga where naziv=:nazivId");

upit.setString("nazivId", knjiga);

}

U prethodnom primeru, nazivId je promenljiva zaduzena za cuvanje vred-nosti ulaza – naziva knjige u ovom slucaju. Imenima parametara u upitimaprethodi dvotacka.

Moguce je u jednom upitu koristiti vise imenovanih parametara:

Query upit = sesija.createQuery(

"from Knjiga where naziv=:nazivId and k_sifra=:IdKnjige");

upit.setString("nazivId", "Prokleta Avlija");

upit.setInteger("IdKnjige",102);

Opcija IN

Nekada je potrebno izdvojiti podatke koji zadovoljavaju kriterijum da nekavrednost pripada datoj listi vrednosti. Na primer, zelimo da izdvojimo knjigeciji je izdavac “Prosveta” ili “Sluzbeni glasnik”. U toj situaciji mozemo isko-ristiti HQL-ovu opciju IN, koja je ekvivalentna koriscenju SQL-ovog operatoraIN. Listu pravimo koriscenjem standardne Java kolekcije ArrayList. Nakontoga mozemo iskoristiti metod setParameterList nad upitom, koji prihvatalistu stavki kojom treba popuniti datu parametarsku listu:

Page 123: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 123

private void izdvojiKnjigeParametarskaLista() {

{

...

// definisemo listu i popunjavamo je nasim kriterijumima

List listaIzdavaca = new ArrayList();

listaIzdavaca.add("Prosveta");

listaIzdavaca.add("Sluzbeni glasnik");

// pravimo upit

Query upit = sesija.createQuery("from Knjiga

where izdavac in (:listaIzdavaca)");

// imenovali smo parametar koji referise na listu izdavaca

upit.setParameterList("listaIzdavaca", listaIzdavaca);

List<Knjiga> knjige = upit.list();

...

}

Kada konstruisemo listu koja sadrzi zadate kriterijume, prosledujemo jeupitu koriscenjem metoda setParameterList. Hibernate transformise ovajupit u ekvivalentan SQL upit:

SELECT * from Knjige where izdavac in

(’Prosveta’,’Sluzbeni glasnik’)

Alijasi

Ponekad zelimo da imenujemo objekat koji izdvajamo. Imena koja dajemotabelama nazivaju se alijasi i posebno su korisna prilikom spajanja tabela ilikoriscenja podupita. Na primer:

Query upit = sesija.createQuery(

"from Knjiga as k where k.naziv=:naziv and

k.k_sifra=:id_knjige");

Kljucna rec AS je opciona.

Iteratori

Metod list primenjen na upit vraca listu, koja ima pridruzeni iterator. It-eratori predstavljaju integralni deo Java kolekcija koji obezbeduje mogucnostiteriranja kroz listu. Da bismo dobili iterator, potrebno je pozvati metod iterator

nad listom, kao u narednom fragmentu koda:

Query upit = sesija.createQuery("from Knjige");

Iterator iteratorUpita = upit.list().iterator();

while(iteratorUpita.hasNext()){

Knjiga k = (Knjiga)iteratorUpita.next();

System.out.println("Knjiga:" + k);

}

Page 124: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

124GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Select

Operator SELECT u HQL-u radi na isti nacin kao i u SQL-u. Ukoliko zelimo daizdvojimo odabrane kolone iz baze podataka (umesto cele redove) moramokoristiti kljucnu rec SELECT (ne postoji razlika u koriscenju malih i velikihslova, kao i kod ostalih operatora).

Na primer, ako zelimo da izdvojimo samo nazive knjiga (a ne sve kolone)za sve knjige iz tabele, mogli bismo to uraditi na sledeci nacin:

Query upit = sesija.createQuery("SELECT k.naziv from Knjiga as k");

List<String> nazivi = upit.list();

System.out.println("Nazivi knjiga:");

for (String naziv : nazivi) {

System.out.println("\t" + naziv);

}

Obzirom da izdvajamo samo jednu kolonu, poznat je ocekivani tip te kolone.Sta se desava ako upit izdvaja vise kolona – na koji nacin se onda vraca rezul-tujuci skup? U situaciji kada se izdvaja n kolona, rezultujuci skup vraca se uvidu n-torki, kao u narednom primeru:

private void izdvojiKnjigeSaTorkama() {

...

String SELECT_UPIT_VISE_KOLONA =

"SELECT k.naziv, k.izdavac from Knjige as k";

Query upit = sesija.createQuery(SELECT_UPIT_VISE_KOLONA);

Iterator it = upit.list().iterator();

while(it.hasNext()){

Object[] o = (Object[])it.next();

System.out.print("Naziv:"+o[0]+"\t");

System.out.println("Izdavac:"+o[1]);

}

}

Lista izdvojenih stavki se prosleduje kao niz objekata. Naziv i izdavac sestoga izdvajaju kao prvi i drugi element niza.

Rad sa n-torkama nije najelegantniji. Efikasnija alternativa je koriscenjejos jedne mogucnosti Hibernate-a, a to je prebacivanje rezultata u domenskiobjekat. Pretpostavimo da imamo instancu Knjiga sastavljenu od naziva iizdavaca. Potrebno je kreirati instancu svakog reda podataka koji izdvajamona sledeci nacin:

String upit = "SELECT new Knjiga(k.naziv, k.izdavac) from Knjige as k";

// izdvajamo knjige

List<Knjiga> knjige = sesija.createQuery(upit).list();

for (Knjiga knjiga : knjige) {

System.out.println("Knjiga: " + knjiga);

}

Page 125: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 125

Primetimo instanciranje objekta Knjiga u samom upitu.

Agregatne funkcije

Hibernate podrzava agregatne funkcije poput AVG, MIN, MAX, COUNT(*) kojesu ekvivalentne odgovarajucim funkcijama u SQL-u. Na primer, ako bi utabeli Knjige bila prisutna informacija o preporucenoj ceni knjige, maksi-malnu cenu knjige bismo mogli da izdvojimo na sledeci nacin:

List cena = sesija.createQuery("select max(cena) from Knjige")

.list();

Azuriranje i brisanje

Podatke je moguce azurirati i obrisati koriscenjem metoda executeUpdate.Ovaj metod kao argument ocekuje string koji sadrzi upit, kao u narednomprimeru:

String update_upit = "update Knjiga set naziv = :naziv

where k_sifra = 102";

Query upit = sesija.createQuery(update_upit);

upit.setParameter("naziv", "Don Kihot");

int uspeh = upit.executeUpdate();

Prethodni upit koristi vezni parametar za postavljanje naziva za slog cijaje sifra 102. Metod executeUpdate azurira tabelu i vraca ceo broj kao indika-tor uspesnosti operacije azuriranja. Povratna vrednost sadrzi broj redova kojisu pogodeni ovom operacijom. Isti metod se moze iskorititi i za izvrsavanjenaredbe brisanja:

String delete_upit = "delete from Knjiga where id=106";

Query upit = sesija.createQuery(delete_upit);

int uspeh = upit.executeUpdate();

Kriterijumi

U Hibernate-u, pored vec videnog nacina za filtriranje podataka od interesa,postoji i alternativni nacin koji koristi kriterijume. Kriterijum je mehanizamkojim se uslovi postavljaju na samom entitetu. Hibernate koristi klasu Criteria,zajedno sa klasom Restrictions kroz koju je moguce postaviti uslove za fil-triranje.

Pretpostavimo da zelimo da izdvojimo podatke o knjizi “Na Drini cuprija”.To je moguce uraditi na sledeci nacin:

Criteria kriterijum = sesija.createCriteria(Knjiga.class);

List knjiga = kriterijum.add(

Restrictions.eq("naziv", "Na Drini cuprija")).list();

System.out.println("Knjiga: " + knjiga);

Page 126: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

126GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Najpre u okviru sesije pravimo instancu klase Criteria a zatim joj doda-jemo restrikcije. Klasa Restrictions ima nekoliko statickih metoda kao sto sueq (jednak), ne (nije jednak), like i slicno. U navedenom primeru izdvajamosve knjige sa datim nazivom. Primetimo da u ovom pristupu nismo koristilinikakav SQL za dobijanje skupa rezultata.

Kriterijumu je moguce dodati restrikcije i njihovim ulancavanjem, kao naprimer:

Criteria kriterijum = sesija.createCriteria(Knjiga.class)

.add(Restrictions.eq("naziv", "Na Drini cuprija"))

.add(Restrictions.between("god_izdavanja",1995,2005))

.add(Restrictions.ne("izdavac","Prosveta"));

Ovo je moguce dodatno pojednostaviti bez koriscenja klase Criteria:

List knjige = sesija.createCriteria(Knjiga.class)

.add(Restrictions.eq("naziv", "Na Drini cuprija"))

.add(Restrictions.between("god_izdavanja",1995,2005))

.add(Restrictions.ne("izdavac","Prosveta")).list();

Prethodni kod za dati kriterijum vrsi izdvajanje knjiga primenom objektno-orijentisanih tehnika.

Ako zelimo da izdvojimo samo nekoliko kolona, mozemo koristiti klasuProjections u te svrhe. Na primer:

// Izdvajamo sve redove za kolonu naziv

List knjiga = sesija.createCriteria(Knjiga.class)

.setProjection(Projections.property("naziv")).list();

// izdvajamo broj redova

knjiga = sesija.createCriteria(Knjiga.class)

.setProjection(Projections.rowCount()).list();

// izdvajamo broj redova kod kojih je definisana vrednost naziva

knjiga = sesija.createCriteria(Knjiga.class)

.setProjection(Projections.count("naziv")).list();

Klasa Projections ima jos nekoliko statickih metoda, kao sto su, na primer,avg (prosek), rowCount (pandan SQL-ovom count(*)), count, countDistinct,max, min . . .

Imenovani upiti

U svim dosadasnjim primerima upite smo formulisali u samom kodu. Hard-kodiranje upita nije bas dobra praksa. Postoje dva nacina da eliminisemo ovoogranicenje. Mozemo koristiti anotaciju @NamedQuery da vezemo upite za en-titete na nivou klasa ili ih mozemo deklarisati u datotekama preslikavanja. Uoba slucaja iz sesije se izdvajaju imenovani upiti.

U pristupu kada koristimo anotacije, entitetu Knjiga potrebno je dodatianotaciju @NamedQuery. Ova anotacija prihvata naziv i sam upit kao u nared-nom primeru:

Page 127: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

4.2. HIBERNATE 127

@Entity(name="Knjiga")

@NamedQuery(name = "Izdvoji_knjige",

query = "from Knjige")

public class Knjiga implements Serializable {

...

}

Jednom kada smo definisali imenovani upit preko anotacije, njemu se mozepristupiti iz sesije u vreme izvrsavanja. Moramo koristiti atribut name dabismo referisali na imenovani upit:

private void koriscenjeImenovanihUpita() {

...

// pristupamo predefinisanom imenovanom upitu

Query upit = sesija.getNamedQuery("Izdvoji_knjige");

List knjige = upit.list();

}

Za jedan isti entitet moguce je vezati vise razlicitih upita, dodavanjem pojedne anotacije @NamedQuery roditeljskoj anotaciji @NamedQueries:

@Entity(name = "Knjiga")

@NamedQueries(

value = {

@NamedQuery(name = "Izdvoji_knjige", query = "from Knjige"),

@NamedQuery(name = "Izdvoji_knjige_za_naziv",

query = "from Knjige where naziv=:naziv")

}

)

public class Knjiga implements Serializable { ... }

Anotacija @NamedQueries prihvata kao argument vrednost, koja je sacinjenaod niza definicija @NamedQuery. Ako koristimo preslikavanja u vidu XML da-toteka, potrebno je definisati upite u datotekama preslikavanja. Na primer,definisemo upite koji su vezani za knjige u datoteci Knjiga.hbm.xml na sledecinacin:

<hibernate-mapping>

<class name="Knjiga" table="Knjige">

...

</class>

<!-- Ovde definisemo upite vezane za entitet -->

<query name="Izdvoji_knjige">

<![CDATA[ from Knjige ]]>

</query>

<query name="Izdvoji_knjige_za_naziv">

<![CDATA[ from Knjige where naziv=:naziv ]]>

</query>

</hibernate-mapping>

Dobra praksa je “omotati” tekst upita u CDATA, da XML parser ne bi izbaciogresku za neke specijalne XML karaktere kao sto je ’>’, ’<’ i slicno.

Page 128: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

128GLAVA 4. OBJEKTNO-RELACIONO PRESLIKAVANJE I ALAT

HIBERNATE

Koriscenje “cistog” SQL-a

Hibernate takode podrzava mogucnost izvrsavanja “cistih” SQL upita. Metodsesija.createSQLQuery vraca SQL objekat, slicno kao sto createQuery vracaQuery objekat. Ova klasa nasleduje klasu Query. Obzirom da je HQL zgo-dan i jednostavan, zasto koristiti SQL? Kada postoje specijalni upiti koji moguda zavise od funkcija specificnih za proizvod baza podataka koristimo SQL.Primer koriscenja SQL-a dat je u nastavku:

SQLQuery upit = sesija.createSQLQuery("select * from Knjige");

List zaposleni = upit.list();

Mozemo primetiti da je string upita ispravna SQL naredba (na primer, pos-toji kljucna rec SELECT na pocetku upita koja se preskace u slucaju HQL-a).Kao sto smo vec pomenuli, SQL upite je moguce deklarisati i van koda. Naprimer, imenovane upite mozemo koristiti dodavanjem anotacije NamedQuery

na samom entitetu, ili deklarisanjem elementa <sql-query> u datoteci pres-likavanja.

Page 129: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

Glava 5

Administracija baza podataka

5.1 Kreiranje baze podataka

Prilikom implementacije baze podataka, postoje brojni faktori koje treba raz-motriti, a koji se ticu fizickog okruzenja u kome ce baza biti implementirana.Medu njima su odabir instance u kojoj ce baza podataka biti kreirana, kolicinaprostora potrebna za smestanje podataka, informacija o tome gde ce podacibiti fizicki smesteni, kao i to koja vrsta prostora tabela ce biti koriscena zasmestanje podataka.

Slika 5.1: Hijerarhijska organizacija instance menadzera baze podataka

Baze podataka se kreiraju unutar instance menadzera baze podataka (engl.Database Manager Instance). Menadzer baze podataka je racunarski programkoji obezbeduje osnovnu funkcionalnost baza podataka, kao sto je kreiranjei odrzavanje baze podataka. Instanca je logicko okruzenje menadzera bazapodataka u okviru koga je moguce bazu podataka uneti u katalog (eng. tocatalog) i postaviti joj konfiguracione parametre. Moguce je kreirati vise odjedne instance na istom fizickom serveru (jednu, na primer, mozemo koris-titi kao razvojno okruzenje, a drugu kao okruzenje za produkciju). U okvirusvake instance moguce je definisati jednu ili vise baza podataka. Svaka bazapodataka moze imati tri ili vise pridruzenih prostora tabela jer DB2 prilikompravljenja baze podataka pravi tri podrazumevana prostora tabela. Naravno,

129

Page 130: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

130 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

moguce je praviti i dodatne prostore tabela za skladistenje tabela, indeksa i sl.Prostori tabela predstavljaju logicki sloj izmedu baze podataka i tabela koje secuvaju u okviru baza podataka. Dakle, prostori tabela se prave unutar bazepodataka, dok se tabele prave unutar prostora tabela.

Prilikom pravljenja baze podataka, potrebno je obezbediti nekoliko tipovaskladista za podrsku novoj bazi. Za svaku bazu podataka potrebno je obezbe-diti skup kontrolnih datoteka baze podataka, kao sto su datoteka konfigu-racije baze podataka, istorija oporavka, skup kontrolnih log datoteka, da-toteke upravljanja prostorom tabela, i druge. Takode, za svaku bazu podatakapotreban je skup log datoteka baze podataka. Podrazumevana vrednost putanjebaze podataka definisana je opcijom dftdbpath u DATABASE MANAGER CONFIGURATION.Podrazumevano, to je home direktorijum vlasnika instance na Linux i UNIXsistemima, odnosno drajv na kome je DB2 instaliran na Windows sistemima.Za rad sa konfiguracijom menadzera baza podataka postoje naredbe:

• GET DATABASE MANAGER CONFIGURATION ili skraceno GET DBM CFG i

• UPDATE DATABASE MANAGER CONFIGURATION ili skraceno UPDATE DBM CFG

Ovo je analogno vec videnim naredbama GET DATABASE CONFIGURATION iUPDATE DATABASE CONFIGURATION.

Svaka baza podataka pravi se sa tri podrazumevana sistemska prostora tabela:

• SYSCATSPACE: tabele kataloga DB2

• TEMPSPACE1: privremene sistemske tabele (koje recimo omogucavaju pros-tor za rad za sortiranje ili spajanje, obzirom da ove aktivnosti zahtevajudodatan prostor za obradu redova u rezultatu)

• USERSPACE1: inicijalni prostor tabela za definisanje korisnickih tabela iindeksa

Prilikom kreiranja baze podataka mogu se definisati automatske putanjeskladista, sa ciljem da omoguce automatsko upravljanje skladistima za pros-tore tabela. Ako je omoguceno automatsko skladistenje, DB2 ce podrazumevanokoristiti automatsko upravljanje skladistem. Medutim, moguce je zadati i dase koristi neki drugi nacin upravljanja prostorom tabela. DB2 podrzava tritipa upravljanja skladistem za prostore tabela i to su:

• baza podataka upravlja skladistem (DMS),

• sistem upravlja skladistem (SMS),

• automatsko skladistenje.

Sva tri tipa je moguce koristiti u jednoj bazi podataka. Tip upravljanja skla-distem se postavlja prilikom pravljenja prostora tabela.

U prostorima tabela kod kojih baza podataka upravlja skladistem (engl.Database Managed Storage ili DMS), menadzer baze podataka kontrolise pros-tor u kome se skladisti. Model skladistenja se sastoji od ogranicenog brojauredaja ili datoteka. Administrator baze podataka odlucuje koji se uredaji idatoteke koriste i DB2 upravlja prostorom na ovim uredajima i datotekama.

Page 131: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.1. KREIRANJE BAZE PODATAKA 131

U ovom pristupu prostor tabela je sustinski implementacija sistema datotekaspecijalne namene koja se dizajnira da najbolje zadovolji potrebe menadzerabaze podataka. Kada se tabela obrise iz DMS prostora tabela, dodeljene stran-ice su na raspolaganju drugim objektima u tom prostoru tabela, ali se prostorna disku ne oslobada. DMS prostori tabela se razlikuju od prostora tabelakojima upravlja sistem (engl. System Managed Storage ili SMS) jer se DMSprostori tabela alociraju prilikom pravljenja prostora tabela, dok se kod SMSprostora tabela, prostor alocira prema potrebama.

U SMS prostorima tabela, menadzer fajl sistema operativnog sistema alo-cira i upravlja prostorom u kome se cuvaju tabele. Model skladista se obicnosastoji od velikog broja datoteka, koje predstavljaju objekte tabele i cuvaju se uprostoru fajl sistema. Korisnik odlucuje o lokaciji datoteka, DB2 vrsi kontrolunjihovih imena, a fajl sistem je odgovoran za njihovo upravljanje. Prilikombrisanja tabele, pridruzene datoteke se brisu te se prostor na disku oslobada.Pocev od verzije DB2 10.1 SMS prostori tabela smatraju se zastarelim za ko-risnicki-definisane trajne prostore tabela, ali se i dalje koriste za kataloge iprivremene prostore tabela.

U bazama podataka za koje nije omoguceno automatsko skladistenje, pri-likom pravljenja prostora tabela komandom CREATE TABLESPACE <prostor_tabela>

mora biti zadata klauzula MANAGED BY DATABASE ili MANAGED BY SYSTEM. Koriscenjeovih klauzula rezultuje u pravljenju DMS prostora tabela, odnosno SMS pros-tora tabela. Ukoliko je za bazu podataka omoguceno automatsko skladistenje,postoji jos jedan izbor, a to je da se prilikom pravljenja prostora tabela navedeklauzula MANAGED BY AUTOMATIC STORAGE cime se obezbeduje da se vrsi au-tomatsko upravljanje prostorom tabela. Ako se klauzula MANAGED BY ... upotpunosti izostavi onda se podrazumeva automatsko skladistenje. Kod au-tomatskog upravljanja skladistenjem, SMS prostori tabela se koriste za privre-mena skladista, a DMS za ostale tipove skladista.

Sintaksa naredbe CREATE DATABASE

Naredba CREATE DATABASE inicijalizuje novu bazu podataka, pravi tri inici-jalna prostora tabela, pravi sistemske tabele i alocira log datoteku oporavka.Prilikom inicijalizacije nove baze podataka, podrazumevano se poziva naredbaAUTOCONFIGURE, kojom se vrsi automatsko podesavanje konfiguracionih para-metara na osnovu raspolozivih resursa.

Na primer, naredbom:

CREATE DATABASE TEST1 ON ’/DATA1’,’/DATA2’ DBPATH ON ’/DPATH1’

pravimo bazu podataka sa imenom TEST1 na putanji /DPATH1 koriscenjemputanja skladistenja /DATA1 i /DATA2 (definisanim na podrazumevanoj grupiskladista IBMSTOGROUP). Grupa skladista je imenovani skup putanja skladistagde mogu biti smesteni podaci. Moguce je dodeliti prostore tabela grupiskladista koja najbolje odgovara podacima.

Da bismo na Windows operativnom sistemu napravili bazu TEST2 na dra-jvu D:, sa skladistem na E:\DATA, potrebno je pokrenuti naredbu:

CREATE DATABASE TEST2 ON ’E:\DATA’ DBPATH ON ’D:’

Page 132: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

132 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

U ovom primeru E:\DATA se koristi kao putanja skladista definisana zapodrazumevanu grupu skladista IBMSTOGROUP.

Ako imamo naredbu:

CREATE DATABASE knjige1 ON /bpknjige1

putanja baze podataka za ovu bazu bila bi /bpknjige1. Baza podataka biimala omoguceno automatsko skladistenje sa jednom automatskom putanjomskladista /bpknjige1.

U primeru naredbe:

CREATE DATABASE knjige2 AUTOMATIC STORAGE NO ON /bpknjige2

putanja baze podataka bila bi /bpknjige2. Za ovu bazu podataka bilo bionemoguceno automatsko skladistenje i bilo bi korisceno SMS upravljanje zatri sistemska prostora tabela

Ako bismo imali naredbu:

CREATE DATABASE knjige3 AUTOMATIC STORAGE YES

ON /bpauto31,/bpauto32,/bpauto33

DBPATH ON /bpknjige3

putanja baze podataka bila bi /bpknjige3, za bazu bi bilo omoguceno au-tomatsko skladistenje sa tri putanje automatskog skladista: /bpauto31, /bpauto32,/bpauto33. Prostori tabela sa automatskim skladistenjem smanjuju zadatkeodrzavanja koje korisnik treba da obavi.

U okviru naredbe CREATE DATABASE moguce je navesti klauzulu USING

CODESET <kodni-skup> TERRITORY <teritorija> COLLATE USING <uparivanje>.Na primer, za Srbiju moguce je navesti:

CREATE DATABASE knjige4 AUTOMATIC STORAGE yes

USING CODESET utf-8 TERRITORY rs

Pocev od verzije DB2 9.5 ukoliko se ne navede kodna strana prilikompravljenja baze podataka, podrazumevana kodna strana je UNICODE. Akose eksplicitno zada kodna strana, onda je potrebno zadati i teritoriju. Po-drazumevana vrednost teritorije zavisi od mesta klijenta koji pokrece naredbuCREATE DATABASE. Nakon kreiranja baze podataka nije moguce izmeniti kodniskup niti teritoriju.

Uparivanje (engl. collation) se odnosi na skup pravila kojima se zadajenacin sortiranja i poredenja podataka. Podrazumevana vrednost je SYSTEM izasniva se na vrednosti teritorije baze podataka

Dakle, da rezimirimo, prilikom pravljenja baze podataka izvrsavaju se na-redne operacije:

1. pravi se baza podataka na navedenoj putanji (ili podrazumevanoj putanji)

2. ako je omoguceno automatsko skladistenje, pravi se podrazumevanagrupa skladista pod imenom IBMSTOGROUP

3. prave se prostori tabela SYSCATSPACE, TEMPSPACE1, USERSPACE1

Page 133: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.1. KREIRANJE BAZE PODATAKA 133

4. prave se tabele sistemskog kataloga i logovi oporavka

5. baza podataka se unosi u katalog u direktorijum lokalnih baza podatakai direktorijum sistemskih baza podataka

6. cuvaju se navedeni kodni skupovi, teritorija i uparivanje

7. prave se sheme SYSCAT, SYSFUN, SYSIBM, SYSSTAT

8. ugraduju se prethodno definisane vezne datoteke menadzera baze po-dataka u bazu podataka

9. daju se prava (npr. svim korisnicima se daje pravo SELECT na tabelama ipogledima sistemskog kataloga, kao i prava CREATETAB i CONNECT); in-formacije o tome ko ima koja prava nad kojim objektom nalaze se upogledu sistemskog kataloga SYSCAT.DBAUTH

Za svaku bazu podataka pravi se i odrzava skup tabela sistemskog kat-aloga. Ove tabele sadrze informacije o definicijama objekata baze podataka,kao i informacije o vrstama pristupa koje korisnici imaju na ovim objektima.Svi pogledi sistemskog kataloga se prave prilikom pravljenja baze podatakanaredbom CREATE DATABASE i oni se ne mogu eksplicitno praviti ili brisati.Menadzer baze podataka je zaduzen za pravljenje i odrzavanje skupa pogledakataloga. Razlikujemo dva skupa pogleda. Prvi skup pogleda se nalazi uokviru sheme SYSCAT, ovi pogledi se mogu samo citati i pravo SELECT nadovim pogledima se podrazumevano daje svima (PUBLIC). Drugi skup pogledase nalazi u okviru sheme SYSSTAT i on je formiran na osnovu podskupa pogledakoji se nalaze u okviru sheme SYSCAT. U okviru ovog pogleda sadrzane sustatisticke informacije koje koristi SQL Optimizer. Pogledi u okviru shemeSYSSTAT sadrze neke kolone cije je vrednosti moguce menjati.

Tabela 5.1: Primeri naziva kolona i odgovarajucih objekata

Tabela TABSCHEMA, TABNAMEIndeks INDSCHEMA, INDNAMEPogled VIEWSCHEMA, VIEWNAMEKolona COLNAMETriger TRIGSCHEMA, TRIGNAME

Na primer mozemo izvrsiti upit:

SELECT tabname, tabschema, tbspace

FROM syscat.tables

U okviru baze podataka moguce je praviti pojedinacne objekte baze po-dataka: sheme, tabele, poglede, alijase, indekse, trigere, itd. Necemo se za-drzavati na ovome, jer su ove naredbe vec obradivane u okviru prethodnogkursa o bazama podataka.

Page 134: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

134 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

Premestanje podataka

Naredbom INSERT moguce je dodati jedan ili vise redova podataka u tabeluili pogled (sto se takode realizuje kao umetanje podataka u tabelu na kojoj sepogled zasniva). Medutim, naredba INSERT ne predstavlja najbolji i najbrzinacin za ucitavanje velike kolicine podataka u bazu podataka.

Naredbe IMPORT i EXPORT

Naredbom IMPORT moguce je vrsiti umetanje podataka iz ulazne datotekeu tabelu, pri cemu ulazna datoteka sadrzi podatke iz druge baze podatakaili programa. Naredbu EXPORT moguce je koristiti za kopiranje podataka iztabele u izlaznu datoteku za potrebe koriscenja podataka od strane druge bazepodataka ili programa za tabelarnu obradu podataka. Ova datoteka se mozekasnije koristiti za popunjavanje tabela, cime se dobija zgodan metod za mi-griranje podataka sa jedne baze podataka na drugu.

Moguci su razliciti formati ovih datoteka:

• DEL – ASCII format u kome su podaci medusobno razdvojeni; najcescese koristi za cuvanje podataka u kojima su vrednosti kolona razdvojenespecijalnim katakterom za razdvajanje,

• ASC – ASCII format bez razdvajanja podataka; on se moze koristiti zauvoz podataka iz druge aplikacije koja pravi “ravne” datoteke podatakasa poravnatim podacima po kolonama. Ovaj format se ne moze koristitisa naredbom EXPORT

• IXF – verzija integrisanog formata za razmenu podatka (engl. IntegratedExchange Format). To je binarni format, koji se moze koristiti za prebaci-vanje podataka izmedu operativnih sistema. Ovaj format se najcescekoristi za izvoz podataka iz tabele, tako da je kasnije moguce te iste po-datke uneti u istu ili neku drugu tabelu. Kod ovog formata podataka,tabela ne mora da postoji pre pocetka operacije IMPORT, dok je kod DEL iASC formata potrebno da tabela bude definisana (sa listom kolona i nji-hovim tipovima) pre nego sto se izvrsi operacija IMPORT.

Slika 5.2: ASC format datoteke

Osnovni format naredbe EXPORT je:

EXPORT TO <ime_datoteke> OF <tip_datoteke> [MODIFIED BY <mod>]

[MESSAGES <datoteka_za_poruke>] <select_naredba>

Dakle, ovom naredbom se podaci izvoze iz baze podataka u jedan odnekoliko mogucih formata datoteka. Naredbom SELECT korisnik zadaje koje

Page 135: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.1. KREIRANJE BAZE PODATAKA 135

Slika 5.3: DEL format datoteke

podatke treba izvesti. Podrzani tipovi datoteka su DEL i IXF. Opcijom MODIFIED

BY je za razdvojene podatke moguce zadati nisku karaktera koja se koristi zarazdvajanje. Klauzula MESSAGES <datoteka za poruke> zadaje odrediste nakome treba pisati poruke za gresku i upozorenja koja se jave tokom operacijeizvoza.

Na primer, mozemo imati sledeci niz naredbi:

CONNECT TO bp_knjiga;

EXPORT TO knjiga_export.ixf OF ixf MESSAGES knjiga_poruke.txt

SELECT * FROM knjiga;

Pre poziva naredbe EXPORT potrebno je povezati se na bazu podataka iz kojezelimo da izvezemo podatke.

Sintaksa naredbe IMPORT je sledeca:

IMPORT FROM <ime_datoteke> OF <tip_datoteke> [MODIFIED BY <mod>]

[ALLOW NO ACCESS|ALLOW WRITE ACCESS]

[MESSAGES <datoteka_za_poruke>]

[COMMITCOUNT (n|AUTOMATIC)] [RESTARTCOUNT n]

(INSERT|INSERT_UPDATE|REPLACE|REPLACE_CREATE)

INTO <naziv_tabele>

Podrazumevano se prilikom uvoza podataka postavlja X katanac na tabeliiz koje se izvoze podaci, da bi se sprecilo da konkurentne aplikacije pristupepodacima iz tabele. Ova opcija se moze i eksplicitno zadati navodenjem op-cije ALLOW NO ACCESS. Ako je navedena opcija ALLOW WRITE ACCESS onda sepostavlja IX katanac na tabelu, cime se omogucava konkuretnim aplikacijamada pristupe tabeli.

Opcija COMMITCOUNT n izvodi naredbu COMMIT nakon svakih n redova. Akoje umesto vrednosti n zadata opcija AUTOMATIC, onda sama operacija internoutvrduje kada treba da izvrsi naredbu COMMIT. Opcijom RESTARTCOUNT n za-daje se da se operacija uvoza podataka treba poceti od (n+1)-og reda, dok seprvih n redova preskacu.

Ako je na kraju naredbe IMPORT navedena naredba INSERT onda se po-daci dodaju u tabelu, bez izmene postojecih podataka u tabeli. Ako je nave-dena naredba INSERT UPDATE podaci se dodaju u tabelu ili se menjaju pos-tojeci redovi sa odgovarajucom vrednoscu primarnog kljuca. Ako je nave-dena naredba REPLACE onda se brisu svi postojeci podaci iz tabele i dodajunovi redovi, dok ako je navedena opcija REPLACE CREATE onda ako tabela pos-toji brise se njen sadrzaj i dodaju novi redovi, a ako tabela ne postoji ona sepravi.

Na primer, mozemo imati narednu naredbu:

Page 136: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

136 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

IMPORT FROM knjiga_dat.ifx OF ixf MESSAGES poruke.txt

INSERT INTO knjiga

Naredba LOAD

Pored operacije IMPORT, podatke je moguce dodati u tabelu i koriscenjem op-eracije LOAD. Ove dve operacije imaju slicnu namenu, ali se u mnogo cemurazlikuju. Naredbom IMPORT se u stvari izvodi INSERT, te su stoga njenemogucnosti slicne onima kad se u programu poziva naredba INSERT. Operaci-jom LOAD se formatiraju stranice i one se direktno upisuju u bazu podataka.

Operacijom LOAD moguce je efikasno prebaciti veliku kolicinu podataka unovokreirane tabele ili u tabele koje vec sadrze podatke. Brza je od operacijeIMPORT jer se njome pisu formatirane stranice direktno u bazu podataka.

Operacija LOAD se sastoji iz cetiri faze:

1. faze punjenja

2. faze izgradnje

3. faze brisanja

4. faze kopiranja indeksa

Tokom faze punjenja, tabele se pune podacima i prikupljaju se kljuceviindeksa i statistike tabela. Tacke konzistentnosti (odnosno tacke pamcenja) seuspostavljaju nakon intervala koji se zadaje kroz parametar SAVECOUNT nared-be LOAD. Generisu se poruke kojima se ukazuje na to koliko puta su ulazniredovi uspesno dodati u trenutku tacke konzistentnosti.

U drugoj fazi, fazi izgradnje, prave se indeksi zasnovani na kljucevimaindeksa sakupljenih tokom faze punjenja. Kljucevi indeksa se sortiraju tokomfaze punjenja.

Tokom faze brisanja, iz tabele se brisu redovi koji narusavaju ogranicenjajedinstvenog kljuca ili primarnog kljuca. Ovi obrisani redovi se cuvaju u tabeliizuzetaka ako je zadata (ona mora biti kreirana pre poziva operacije LOAD), aporuke o odbacenim redovima se pisu u datoteku poruka. Nakon zavrsetkaoperacije LOAD pozeljno je pregledati ovu datoteku, razresiti svaki problem iuneti izmenjene redove u tabelu.

Tokom faze kopiranja indeksa, indeksirani podaci se kopiraju iz sistem-skog privremenog prostora tabela u originalni prostor tabela. Ovo ce se desitisamo ako je prilikom poziva naredbe LOAD zadat sistemski privremeni prostortabela za pravljenje indeksa opcijom READ ACCESS.

Sintaksa naredbe LOAD je:

LOAD FROM <datoteka> OF [ASC|DEL|IXF] [MODIFIED BY <mod>]

[SAVECOUNT n] [ROWCOUNT n] [WARNINGCOUNT n]

[MESSAGES <datoteka_za_poruke>]

(INSERT|REPLACE|RESTART|TERMINATE) INTO <naziv_tabele>

[FOR EXCEPTION <tabela_izuzetaka>]

[ALLOW NO ACCESS| ALLOW READ ACCESS [USE naziv_prostora_tabela]]

Page 137: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.2. PRAVLJENJE REZERVNIH KOPIJA I OPORAVAK 137

Opcijom SAVECOUNT n zadaje se da se operacijom LOAD tacke konzistent-nosti postavljaju na svakih n redova. Ova vrednost se konvertuje u broj stran-ica i zaokruzuje. Opcijom ROWCOUNT n se zadaje da se iz datoteke ucitava samoprvih n slogova. Ako se zada opcija WARNINGCOUNT n, operacija LOAD se zaus-tavlja nakon n upozorenja.

Postoje cetiti moda pod kojima se operacija LOAD moze izvrsavati: INSERT,REPLACE, RESTART, TERMINATE. Ako se navede naredba INSERT onda se po-daci dodaju u tabelu bez izmene postojecih podataka u tabeli, ako se navedeopcija REPLACE brisu se postojeci podaci iz tabele i ucitavaju novi podaci, dokse definicije tabele i indeksa ne menjaju. Ukoliko se navede opcija RESTART

ponovo zapocinje prethodno prekinuta operacija LOAD i ona se automatskinastavlja od poslednje tacke konzistentnosti. Ako se navede opcija TERMINATE

prekida se prethodno prekinuta operacija LOAD i vrsi povratak na tacku ukojoj je ona pocela; pritom se ponistavaju akcije od tog momenta nadalje,bez obzira na to sto se mozda uspesno stiglo do nekih tacaka konzistent-nosti. Dakle, kada se pokrene naredba LOAD ciljna tabela se prebacuje u stanje“ucitavanje u toku”. Ukoliko se ova operacija iz nekog razloga ne zavrsiuspesno, tabela prelazi u stanje “ucitavanje zaustavljeno”. Da bi tabela izaslaiz ovog stanja, moze se zahtevati naredba LOAD TERMINATE da se operacijaponisti, moze se zahtevati naredba LOAD REPLACE da se ponovo ucita kom-pletna tabela ili LOAD RESTART. Obicno je ovo poslednje najbolja varijanta jerse stedi vreme time sto se ucitavanje nastavlja od poslednje uspesne tackepamcenja.

Dakle, razlike izmedu naredbi IMPORT i LOAD su sledece. Dok se nared-bom IMPORT mogu kreirati ciljne tabele, ako je ulaz datoteka u IXF formatu,onda se operacijom LOAD podaci dodaju postojecoj tabeli. Koriscenjem op-cije ALLOW WRITE ACCESS za operaciju IMPORT moze se izbeci zakljucavanjena nivou tabele, ali bi onda bilo dobro koristiti opciju COMMITCOUNT da bi seizbegla ekskalacija katanaca za vece ulazne datoteke. Operacija LOAD doz-voljava konkuretna citanja drugih aplikacija ako je postavljena opcija ALLOW

READ ACCESS za LOAD INSERT. Operacija IMPORT moze da iskoristi prostor ustranicama tabele koji je ostao prazan nakon brisanja redova, dok operacijaLOAD uopste ne pokusava da iskoristi slobodan prostor u postojecim strani-cama.

5.2 Pravljenje rezervnih kopija i oporavak

Naredba BACKUP DATABASE

Naredbom BACKUP DATABASE moguce je napraviti kopiju podataka iz baze po-dataka i sacuvati je na nekom drugom medijumu. Ovi podaci se dalje mogukoristiti u slucaju pada medijuma i stete na originalnim podacima. Moguceje napraviti rezervnu kopiju cele baze podataka, particije ili samo odredenihprostora tabela.

Prilikom pravljenja rezervne kopije baze podataka, nije neophodno bitipovezan na bazu podataka; operacija pravljenja rezervne kopije automatskiuspostavlja vezu sa bazom podataka i ova veza se prekida nakon uspesnogzavrsetka operacije BACKUP. Ime baze podataka moze biti lokalno ili da odgo-vara udaljenoj bazi podataka.

Osnovna sintaksa naredbe BACKUP je sledeca:

Page 138: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

138 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

BACKUP DATABASE alijas_bp [USER username [USING password]]

TO dir/dev

Na svim operativnim sistemima, imena datoteka koje se koriste kao slikerezervnih kopija koje se prave na disku sastoje se od nekoliko nadovezanihelemenata, razdvojenih tackom, formata:

alijas_bp.tip.ime_inst.BPPARTnnn.timestamp.redni_br

Na primer: Knjiga.0.DB201.DBPART000.20150922120112.001. Ovi ele-menti redom oznacavaju:

• alijas bp – alijas baze podataka: ovo je naziv duzine od 1 do 8 karak-tera koji se zadaje prilikom pozivanja operacije BACKUP

• tip – tip operacije pravljenja rezervne kopije, pri cemu 0 oznacava pravl-jenje kompletne kopije na nivou baze podataka, 3 predstavlja pravljenjerezervne kopije na nivou prostora tabela, a 4 pravljenje slike rezervnekopije

• ime inst – naziv instance: ovo je naziv tekuce instance, duzine izmedu1 i 8 karaktera, koji se uzima iz promenljive okruzenja DB2INSTANCE

• BPPARTnnn – broj particije baze podataka - u okruzenjima baza podatakasa jednom particijom, ovo je uvek DBPART000. U okruzenjima u kojimapostoje particije, ovaj parametar ima vrednost DBPARTxxx, gde je xxx brojpridruzen particiji baze podataka u datoteci db2nodes.cfg.

• timestamp – reprezentacija datuma i vremena u vidu niske od 14 karak-tera koja predstavlja u kom trenutku se izvela operacija pravljenja re-zervne kopije, njen format je yyyymmddhhnnss pri cemu:

– yyyy predstavlja godinu (1995 do 9999)

– mm predstavlja mesec (01 do 12)

– dd predstavlja dan u mesecu (01 do 31)

– hh predstavlja sate (00 do 23)

– nn predstavlja minute (00 do 59)

– ss predstavlja sekunde (00 do 59)

• redni br – trocifreni broj koji se koristi kao ekstenzija datoteke

Na primer, naredbom:

BACKUP DATABASE bp_knjiga TO /backup

vrsi se pravljenje rezervne kopije u datom direktorijumu.

Page 139: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.2. PRAVLJENJE REZERVNIH KOPIJA I OPORAVAK 139

Naredba RESTORE

Naredbom RESTORE moguce je povratiti bazu podataka cija je rezervna kopijabila napravljena koriscenjem naredbe BACKUP. Najjednostavniji oblik RESTORE

naredbe zahteva samo da se navede naziv alijasa baze podataka koju zelimoda povratimo. Na primer,

RESTORE DATABASE bp_test

U slucaju da baza podataka sa ovim nazivom postoji, ona ce ovom operaci-jom biti zamenjena, te se vraca naredna poruka:

SQL2539W Warning! Restoring to an existing database that is the

same as the backup image database. The database files will be

deleted. Do you want to continue ? (y/n) If you specify y,

the restore operation should complete successfully.

Naredba RESTORE DATABASE zahteva ekskluzivnu konekciju, tj. prilikomstartovanja operacije nijedna druga aplikacija ne sme da radi nad tom bazomi sprecava se da bilo koja aplikacija pristupi bazi dok se operacija povratkapodataka ne zavrsi uspesno. Moguce je povratiti bazu podataka iz slike rez-ervne kopije koja je napravljena na 32-bitnom sistemu na 64-bitni sistem, aline i obratno.

Naredba RECOVER DATABASE

Inkrementalno pravljenje rezervnih kopija podrazumeva da uzastopne kopije po-dataka sadrze samo onaj deo podataka koji je menjan od poslednje napravl-jene rezervne kopije. Ono je cesto pozeljnije jer smanjuje prostor koji se koristiza skladistenje i brze se izvodi. Kada je potrebno napraviti punu rezervnukopiju, onda proces restauracije mora da nade poslednju kompletnu rezervnukopiju, a da zatim prode kroz sve inkrementalne rezervne kopije do tackerestauracije.

Naredba RECOVER DATABASE koristi informacije iz datoteke istorije da od-redi sliku rezervne kopije koju treba iskoristiti u odredenom trenutku, te samkorisnik ne mora da zada odredenu sliku rezervne kopije. Ako je zahtevanaslika rezervne kopije inkrementalna rezervna kopija, operacija RECOVER ce poz-vati inkrementalnu automatsku logiku da izvede povratak podataka. Ako sezahteva oporavak u nekom vremenskom trenutku, ali najranija slika rezervnekopije iz datoteke istorije je kasnija od tog vremenskog trenutka, naredbaRECOVER ce vratiti gresku. Inace se za povratak baze podataka koristi slikarezervne kopije iz datoteke istorije sa najkasnijim vremenom pravljenja rez-ervne kopije koje prethodi zahtevanom vremenskom trenutku.

Jednostavni primer ove operacije je:

RECOVER DATABASE bp_test

Page 140: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

140 GLAVA 5. ADMINISTRACIJA BAZA PODATAKA

5.3 Aktivnosti na odrzavanju baze podataka

Naredba RUNSTATS

Tacne statistike o tabelama i indeksima su veoma znacajne za DB2 optimiza-tor koji na taj nacin bira efikasne planove pristupa za obradu zahteva ap-likacije. Naredba RUNSTATS se moze iskoristiti za sakupljanje novih statistikatabela i indeksa. Ako sadrzaj tabele raste ili se dodaju novi indeksi, vazno jeazurirati vrednosti ovih statistika tako da oslikavaju ove promene. DB2 bazapodataka se moze konfigurisati da automatski odredi tabele i indekse za kojeje potrebno izracunati nove statistike.

Na ovaj nacin moguce je dobiti informacije o:

• broju stranica koje sadrze redove

• broju stranica koje su u upotrebi

• broju redova u tabeli

• vrednostima statistika koje se ticu raspodele podataka,

• detaljne statistike za indekse kojima se odreduje koliko je efikasno pris-tupiti podacima preko indeksa, . . .

Na primer, osnovne statistike o tabeli mozemo dobiti pozivom naredbe:

RUNSTATS ON TABLE knjiga

U okviru ove naredbe moguce je navesti mnogo dodatnih opcija. Na primer,za velike tabele mozemo da koristimo uzorkovanje umesto da obradujemocitav skup podataka.

Na primer, osnovne statistike o tabeli i detaljne statistike o svim indek-sima, koriscenjem uzorkovanja, mozemo sakupiti koriscenjem naredbe:

RUNSTATS ON TABLE knjiga AND SAMPLED DETAILED INDEXES ALL

Naredbe REORG i REORGCHK

Naredba REORG se moze iskoristiti za reogranizaziju tabela i indeksa da bise popravila efikasnost skladistenja i takode smanjili troskovi pristupa. Naprimer, ako se iz tabele brise mnogo redova, veliki broj stranica tabele mozeda sadrzi malo ili nista od podataka. U toj situaciji moze se primeniti op-eracija REORG za ponovnu izgradnju tabele tako da koristi manje stranica, cimese stedi prostor na disku i sadrzaj tabele se moze skenirati sa manjim brojemulazno/izlaznih operacija. Na primer:

REORG TABLE s1.tabela1 USE TEMPSPACE1

Ovom naredbom se tabela reorganizuje koriscenjem privremenog prostoratabela.

Ako bismo hteli da reorganizujemo sve indekse nad tabelom, to bi bilomoguce uraditi naredbom:

Page 141: Programiranje baza podatakapoincare.matf.bg.ac.rs/~nina/PBP19/pbp.pdf · GLAVA 2. NACINI KORIˇ SˇCENJA BAZA PODATAKA U VI´ SIMˇ PROGRAMSKIM JEZICIMA negativnu vrednost, ako se

5.3. AKTIVNOSTI NA ODRZAVANJU BAZE PODATAKA 141

REORG INDEXES ALL FOR TABLE s1.tabela1

Naredba REORGCHK se moze koristiti za dobijanje preporuka koje tabele ikoji indeksi bi imali koristi od reorganizacije. Nakon toga se moze iskoristitiREORG naredba za implementiranje kompresije postojecih tabela i indeksa.

Primer naredbe:

REORGCHK ON SCHEMA AUTO

Za svaku tabelu ove sheme racuna se po nekoliko formula da li bi je tre-balo reorganizovati i ako izracunata vrednost premasi preporucenu vrednostispisuje se *. Slicno je i za indekse.