PC Press
O nama
O nama
Pretplata
O nama
Postanite saradnik PC-ja
Kontakt sa redakcijom
PC Press
Novi broj
Novi broj   
Pretrazivanje
Arhiva
Arhiva   
PC Online
PC Plus   
Specijalna izdanja
Programiranje Programiranje
PC #28 : Oktobar 1997 Knjiga 50 godina racunarstva u Srbiji

 Naslovna  Sadržaj 
Ivan Mitrović  

Java i baze podataka

Java Development Kit 1.1 je doneo ono što je ogroman broj Java programera nestrpljivo očekivao. Ivan Mitrović predstavlja ovaj paket.

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 "nezavisna 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 podatke 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 da se zadaju uobičajeni 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, pa 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";
}

Pošto nismo sigurni koja je SQL rečenica u pitanju, proverićemo oba slučaja. Najpre proveravamo da li se kao rezultat SQL rečenice javio int; ako jeste, radi se o Insert (Update) rečenici, pa nakon uspešne obrade server klijentu šalje poruku o broju slogova na koje je rečenica uticala. 0 indicira da se radi o nula slogova, ali može nastati i kao rezultat DDL komande (Create, Drop); u ovom primeru je to sprečeno:

ResultSet result = stmt.getResultSet ();
if (result != null) {
   try {
     ResultSetMetaData rsmd=result.getMetaData ();
     int cols = rsmd.getColumnCount ();

Ako se radi o Select komandi, prebrojaćemo broj kolona u rezultujućem setu i čitati jedan po jedan slog seta koji je nastao izvršenjem Select SQL rečenice. Svaki slog se, u obliku stringa, predaje klijentu preko Stream-ova, uz korišćenje send metoda. Na kraju server ispisuje poruku "Server message: end":

while (result.next ()) {
   for (int i = 1; i = cols; i ++) {
      if (i > 1) msg1 = msg1 + "   ,   ";
      msg1 = msg1 + result.getString (i);  }
   send ();
   pass = true;
}

Ovaj deo listinga je jedino interesantan sa stanovišta JDBC-a - sve ostalo spada u domen Java klijent / server programiranja i nalikuje Chat sistemu o kome smo govorili pre par meseci (pogledajte www.pcpress.co.yu/arhiva/26/109fr.html).

Kompletan kod primera pogledajte na www.pcpress.co.yu/JDBC. Primetićete da primer ima tri opcije: upis novog studenta, prijavljivanje na kurs i pregled baze. Pregled baze je najfleksibilnija opcija koja omogućava i da upisujete SQL rečenice i šaljete ih preko server aplikacije bazi; upotreba DDL rečenica nije moguća. Querry builder će pomoći u izradi SQL upita: selektujte polja koja želite da vidite u rezultatu, kliknite na Make Querry i dobićete SQL rečenicu u kontroli tipa TextArea. U ovu kontrolu upisujete i sopstvene SQL rečenice; nakon klika na ExecuteQuerry, rečenica će biti izvršena.

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 komunikacija otvara neslućene poslovne mogućnosti.

Pored očiglednih prednosti i ogromnog napora koji je učinjen da se Java Database Connectivity 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 programerski, 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: end";
  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: end";
   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;
}

Prilozi:

pc028jdb.zip (221,45 kB)