Java i baze podataka |
Ivan Mitrović |
Java Development Kit 1.1 je doneo ono što je ogroman broj Java programera nestrpljivo očekivao: Enterprise API, koji izdiže Javu iznad "jezika za Web strane" i ubacuje je u oblast distribuiranog programiranja i baza podataka... |
Java Database Connectivity je prvi standardizovani set objekata i metoda za interakciju sa bazama podataka. JDBC je deo JDK 1.1, ali se može nezavisno distribuirati i, uz manje izmene, prilagoditi za JDK 1.0.2. Integracijom Java Enterprise API-ja (JDBC je deo Java Entrprise API-ja) u JDK 1.1, Java programeri su dobili snažno oruđe koje im omogućava da primene koncept "nezavisn platforma - nezavisna baza". Java apleti i aplikacije sada migu podjednako lako pristupati bilo kojoj bazi podataka na bilo kojoj platformi. Iako je u nazivu JDBC pomenuta baza podataka, stvari kao što su oblik, lokacija i organizacija nisu bitni za Java program koji koristi JDBC, sve dok postoji odgovarajući drajver. Podaci mogu dolaziti iz baze podataka ili biti video signali sa satelita; obrađivaće se na isti način.
JDBC je baziran na popularnoj Microsoft-ovoj implementaciji ODBC-a - to je najrasprostranjeniji koncept, pa je bilo logično da se programeri firme Javasoft opredele baš za njega. SUN je otišao korak dalje, napravivši JDBC-ODBC most, preko koga JDBC može da komunicira sa bilo kojom bazom koja ima ODBC drajver. ODBC je, doduše, interfejs baziran na C-u, pa se ne može "učitati u aplet", ali je veoma pogodan za troslojne (three tier) i višeslojne (multi tier) klijent / server sisteme.
Klijent / server sistemi
Najveći broj informacionih sistema obuhvata module koji krajnjem korisniku, putem GUI interfejsa, olakšavaju pregled i unos podataka, ali i proveravaju podatake i manipulušu bazom. Moduli su organizovani u obliku klijent / server sistema, u dva, tri ili više slojeva.
Dvoslojni klijent / server sistemi obuhvataju module u kojima su GUI i poslovna logika sadržani u istoj aplikaciji (klijentu), dok se relaciona baza nalazi na serveru. Klijent stvara korisničko okruženje i proverava ispravnost podataka. Troslojni klijent / server sistemi zasnovane su na "malom klijentu" (thin client), koji samo stvara GUI, dok podatke prosleđuje jakoj aplikaciji koja se nalazi na serveru i koja rešava poslovnu logiku i preuzima na sebe komunikaciju sa relacionom bazom.
Pojavom Jave u mogućnosti smo da stvorimo višeslojne i višeplatformske klijent / server sisteme. Oni obuhvataju veliki broj jakih server aplikacija i različitih relacionih baza na više nivoa, a klijent može, komunicirajući posebno sa svakom pojedinačnom server aplikacijom, komunicirati sa više baza podataka. Ulogu "malog klijenta" može da odigra i običan applet, što nas uvodi u oblast distribuiranog programiranja, u kojoj se Java programeri osećaju "kao riba u vodi". Putem RMI ili CORBA poziva, Java klijent može pozivati metode na udaljenim serverima i pristupati bazama podataka.
RMI (Remote Method Invocation), koncept koji omogućava Java - Java komunikaciju i pozivanje metoda iz udaljenih Java aplikacija od strane Java appleta, Java IDL (jezik kojim se definišu interfejsi po CORBA standardu u Javi i, preko ORB-a (Object Request Broker), pozivaju metode u programima napisanim u bilo kom programskom jeziku koji podržava CORBA standard) i JDBC postaju jako sredstvo za pisanje distribuiranih, višeslojnih i višekorisničkih klijent / server aplikacija za pristup relacionim bazama podataka. Podatak da su na Zapadu najtraženiji Java programeri upravo sa znanjem JDBC, RMI i CORBA, dovoljno govori o pravcu u kome će se distribuirano Java programiranje razvijati. Zato ćemo na jednostavnom primeru pokazati jednostavnost komunikacije Java programa sa bazom podataka.
Model
Za primer sam izabrao troslojni klijent / server model gde aplet (klijent) Java aplikaciji (server) predaje SQL rečenicu koju server prosleđuje bazi podataka i vraća dobijeni rezultat klijentu. Veza između klijenta i servera ostvarena je soketima, na način koji je opisan u ranijim tekstovima. Baza je Microsoft Access 97 i predstavlja virtualnu učionicu, koja se sastoji od tri tabele: Studenti, Kursevi i StudentiKursevi.
Tabela Studenti čuva podatke o studentima (Identifikacioni broj, Ime, Starost, Pol, e-mail adresa), u tabeli Kursevi su podaci o kursevima (Identifikacioni broj, Naziv) a tabela StudentiKursevi je relaciona tabela između tabela Studenti i Kursevi. Kada se student prijavi na kurs, identifikacioni brojevi studenta i kursa se upisuju u slog tabele StudentiKursevi.
Programski deo obuhvata klijentski aplet koji skuplja podatke iz GUI kontrola i predaje ih preko stream-ova Java server aplikaciji koja ostvaruje vezu sa Access bazom. Za komunikaciju sa bazom preko JDBC - ODBC mosta zadužena je Java server aplikacija sa slike 1.
Da bi se ostvarila konekcija sa bazom podataka, treba pozvati JdbcOdbc most koji će JDBC prevoditi u ODBC i tako komunicirati sa bazom. Driver Manager mora imati URL relacione baze, korisničko ime i lozinku. Ova sigurnosna polja mogu da ostanu prazna, ali se mogu i definisati i traŽiti od korisnika, čime se sprečava neovlašten pristup bazi. URL u ovom primeru je Jdbc:Odbc:sample. Kako je OS na kome se "vrti" Java server aplikacija iz ovog primera Windows NT 4.0, URL se definiše u ODBC32 modulu, izborom drajvera za Microsoft Access, pri čemu u nazivu ODBC izvora treba upisati sample i taj ODBC interfejs dodeliti datoj bazi. Pošto je veza sa bazom uspešno uspostavljena, moguće se zadavati SQL upiti.
SQL rečenice
JDBC prepoznaje tri vrste SQL rečenica koje su primerene standardima: proste SQL rečenice (Statement), pripremljene rečenice (PreparedStatement) i procedure (CallableStatement). Proste SQL rečenice obuhvataju Select, Insert, Update itd bez parametara, dok pripremljene SQL rečenice imaju parametre i koriste se kada istu SQL rečenicu treba primeniti više puta sa različitim argumentima. CallableStatement se koristi za poziv već pripremljenih procedura - obično ih pravi administrator baze.
SQL rečenice mogu biti DML rečenice (Data manipulation Language, takozvane Select, Insert i Update rečenice) i DDL (Data Definition Language) rečenice, odnosno rečenice kojima se kreiraju ili uništavaju tabele (npr. Create, Drop itd). Metodi kojima se izvršavaju SQL rečenice su ExecuteQuerry (String SQL rečenica), ExecuteUpdate (String SQL rečenica) i Execute (String SQL rečenica).
ExecuteQuerry metod se koristi za izvršavanje SELECT upita nad tabelama. Kao argument zahteva SQL rečenicu u obliku stringa, a kao rezultat vraća ResultSet, koji sadrži rezultujuće kolone. Korišćenjem ResultSetMetaData klase mogu da se dobiju podaci o ResultSet-u, recimo broj kolona, njihova imena i slično. ResultSetMetaData je nezamenjiv kada ne znamo u kakvom ćemo obliku dobiti rezultat, pa ga koristimo i u pratećem primeru. ExecuteUpdate metod izvršava INSERT i UPDATE rečenice i kao argument zahteva SQL rečenicu u obliku stringa. Kao rezultat vraća integer, broj slogova na koje je SQL rečenica uticala. Ako smo, recimo, sa Update promenili deset slogova, rezultat će biti 10, ako smo sa Insert u tabelu upisali jedan slog rezultat je 1 i slično.
Execute metod je najfleksibilniji, poa se koristi kada nismo sigurni koja će se rečenica izvršiti. Metod je ujedno i najsloženiji, pošto moramo ispitati da li je bila poslata Select, Insert ili Update rečenica. U primeru sa slike 2 korišćen je Execute metod.
Program sa slike 2 izvršava "nepoznatu" SQL rečenicu i u slučaju greške vraća klijentu odgovarajuću poruku. Predviđeno je da, pored unapred definisanih SQL rečenica, korisnik može poslati i sopstvenu SQL rečenicu čiji je rezultat, naravno, u trenutku programiranja nepoznat:
try { int rows = stmt.getUpdateCount (); msg1 = ""; if (rows >>= 0) { msg1 = "Succesfully executed. Rows affected: " + rows + "\nServer message: end"; } |
ResultSet result = stmt.getResultSet (); if (result != null) { try { ResultSetMetaData rsmd = result.getMetaData (); int cols = rsmd.getColumnCount (); |
while (result.next ()) { for (int i = 1; i <<= cols; i ++) { if (i >> 1) msg1 = msg1 + " , "; msg1 = msg1 + result.getString (i); } send (); pass = true; } |
ResultSet result = stmt.getResultSet (); if (result != null) { try { ResultSetMetaData rsmd = result.getMetaData (); int cols = rsmd.getColumnCount (); |
Zaključak
JDBC je otvorio velike mogućnosti komunikacije sa bazama podataka preko Interneta i intraneta. U saradnji sa RMI i CORBA, primena JDBC u višeplatformskom i višebaznom okruženju postaje praktično neograničena. Koristeći sigurnosne mehanizme Jave, sistem postaje veoma upotrebljiv na Internetu, pa treba očekivati pojavu velikog broja baza podataka na Web-u. Sistem omogućava da zaposleni, noseći svoj notebook sa Java enabled browser-om, pristupaju podacima iz baza svoje kompanije sa bilo koje tačke na planeti. Ovakav koncept otvara neslućene poslovne mogućnosti.
Pored očiglednih prednosti i ogromnog napora koji je učinjen da se JDBC nađe u JDK 1.1, postoje i određeni nedostaci. JDBC ne podržava bookmark ni cursor funkcije, tako da ne možete "skrolovati" po bazi; taj deo problema mora da se rešava programersk, recimo ubacivanjem slogova u vektor ili matricu. Mada su cursor funkcije različite za različite baze podataka, što Javi (koja pretenduje da bude nezavisna od baze) nikako ne odgovara, treba očekivati da ovi nedostaci u budućim verzijama budu otklonjeni.
Slika 1 |
String URL = "jdbc:odbc:sample"; String user = ""; String password = ""; try { Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { e.printStackTrace (); msg1 = "Can't connect to a database!" + "\n" + e.toString() + "\nServer message: send (); return; } try { con = DriverManager.getConnection (URL, user, password); stmt = con.createStatement (); } catch (Exception e) { e.printStackTrace (); msg1 = "Can't connect to a database!" + "\n" + e.toString() + "\nServer message: send (); return; } |
Slika 2 |
try { stmt.execute (msg); } catch (Exception e) { e.printStackTrace (); msg1 = "Error! Check the SQL Sentence!" + "\n" + e.toString() + "\nServer message: end"; send (); return; } |
|