Adatba ziskezeles órela cio s adatba ziskezel k ónoha a Java objektum-elvu, egyel re nem az objektum-elvu adatba ziskezel ket ta mogatja ö Vannak egyaltalan igazan muk d ilyenek? óalapelv: platform-fíggetlenseg, ebbe beletartozik az adatbaziskezel kt l valo fíggetlenseg is ómegoldas: JDBC JDBC óvalami interfesz, amit a Java programok es az adatbaziskezel k k ze lehet rakni óne kelljen olyan ko dot ırni, amely egy picit is egy konkret ABkezel rendszert l fígg óegy muvelethalmaz, amit a Java programozo k haszna lhatnak ófunkcionalitas, amit az adatbaziskezel keszıt jenek meg kell valo sıtania ö JDBC-compliant ószerz des-modell JDBC: Java Data Base Connectivity óadatbaziskezel keszıt je: csinalnia kell egy meghajto -programot (driver), amellyel az adatbaziskezel kielegıti a JDBC specifika cio t ójava programozo : a java.sql es a javax.sql csomagokban talalhato osztalyok, interfeszek segıtsegevel dolgozik, es a programhoz csatolja a hasznalt adatbaziskezel JDBCmeghajto programjat Rela cio s adatba ziskezeles - attekintes óaz adatok fizikai abrazolasa mellekes (remelhet leg hatekony) ólogikailag az adatok relacio kkent jelennek meg óa relacio k tablaknak felelnek meg óa relacio elemei a tabla sorai óa relacio tıpusat az oszlopok hatarozzak meg óa relacio kon muveletek vegezhet k (pl. join) ókitíntetett projekcio k: kulcsok Pelda: bro ker ceg óu gyfelek ta bla Azon. Ne v Cım 1 John Lennon London, Abbey Road 1 2 Jim Morrison LA, Love Street 7 3 Presszer Gabor Bp, Mienkitta ter 3 óreszvenyek tabla Ne v Ar FORTE 190 TVK 120 1
Adatmanipula cio : SQL óstructured Query Language, IBM óelterjedt, burja nzo, de szabva nyosıtotta k (ISO-ANSI, 1988) óa JDBC az ANSI SQL-2 szabvanyt k veti ólekerdezesek, adatfelvitel, t rles, mo dosıtas adatbazis-adminisztra cio Pelda k select * from Ugyfelek select Nev from Reszvenyek where Ar < 150 insert into Reszvenyek (Nev, Ar) values ('MOL',111) update Reszvenyek set Ar=121 where Nev='MOL' delete from Reszvenyek where Nev='MOL' create table Tulajdonok (Azonosıto int, Mennyiseg int) drop table Tulajdonok Mini SQL: msql ónagyon egyszeru adatbaziskezel (Hughes) ónem mindent tud, amit az SQL szerint kene ókis adatbazisokhoz hatekony, kis er forrasigenyu óvan hozza: terminal program, relacio sema nezeget, C-nyelvi API, JDBC meghajto ókliens/szerver tamogatasa TCP/IP-n keresztíl Haszna lat óindıtsuk el az adatbazis motort. Ehhez az msql2d programot kell futtatni. relshow A sema nezeget : milyen adatbazisok vannak relshow StockMarket Milyen tablak vannak benne relshow StockMarket Customer egy tabla definıcio janak megtekintese msql StockMarket belepes a terminal programba, AB megnyitasa Az msql program óirjunk be SQL parancsokat óa vegere \g kell, ez zarja le a parancsot (a parancs lehet t bb soros is) ósegıtseg: \h ókilepes: \q ófa jlbo l parancsok: msql StockMarket <input.txt 2
Eleres TCP/IP-n keresztíl msql -hostname ge pne v adatbazis msql -h ge pne v adatbazis msql -h localhost StockMarket relshow -h localhost StockMarket Stock Az adatbazis elerhet a 1112 TCP porton keresztíl (alapertelmezes szerint) Adatbaziskezeles Java programbo l ójdbc nelkíl: AB-kezel t l fígg ko d, APIhıvasok JNI-n keresztíl (Java Native Interface) ójdbc-vel: ko d, mely fíggetlen az ABkezel t l. Barmikor le lehet cserelni... óaz adatmanipulacio s nyelv tovabbra is az SQL ónem beagyazott, az SQL parancsok sztringekben vannak ö A fordıto nem ellen rzi, futas k zben deríl ki minden hiba... :-( msql es Java óaz msql-jdbc-1-0.jar fajlban van a meghajto program óezt a jar fajlt is hasznaljuk a fordıtaskor es a futtata skor -classpath msql-jdbc-1-0.jar:. ómi van benne? Egy csomo osztaly, ami megvalo sıt fontos interfeszeket ö Driver, Connection, Statement, ResultSet, stb. ö Pl. a com.imaginary.sql.msql.msqldriver osztalyt valahogy a JVM tudomasara kell hozni, mondjuk peldanyosıtani import java.sql.*; class DBTeszt { public static void main(string args[]) throws SQLException { new com.imaginary.sql.msql.msqldriver(); Connection c = DriverManager.getConnection ("jdbc:msql://localhost:1112/stockmarket"); Statement s = c.createstatement(); ResultSet rs = s.executequery ("select * from Stock"); while( rs.next() ){ System.out.println(rs.getString(1)); rs.close(); s.close(); c.close(); Az adatbaziskezeles menete óamikor a JVM bet lti a Driver interfeszt megvalo sıto osztalyt, akkor az beregisztralja magat a DriverManager-nel óa DriverManager-t l kerhetínk egy Connection-t óa Connection-t l egy Statement-et óa Statement-tel vegrehajthatunk egy SQL utasıtast. Lekerdezes eredmenye egy ResultSet óa ResultSet-et bejarhatjuk soronkent Ezeket a kekeket mind megvalo sıtja a meghajto prg. 3
A JDBC meghajto k óegy Java program t bb adatbaziskezel t is haszna lhat ómindegyikhez kell a megfelel meghajto prg. óa DriverManager tartja nyilvan a meghajto kat ókivalasztja a megfelel t: Connection c = DriverManager.getConnection ("jdbc:msql://localhost:1112/stockmarket"); óa programozo dolga csak az, hogy a JVM-mel bet ltesse a Driver-t implementalo osztalyt, mert az automatikusan beregisztralja magat a DriverManager-nel (egy statikus inicializatorral) A meghajto bet ltese ópelda ny letrehoza sa new com.imaginary.sql.msql.msqldriver(); óforname meto dussal try{ Class.forName ("com.imaginary.sql.msql.msqldriver"); catch (ClassNotFoundException exc){ ó.class attribétummal Class cl = com.imaginary.sql.msql.msqldriver.class; ójdbc.drivers jellemz bea llıta sa Hogy a ko d semmi adatbaziskezel -specifikus reszt ne tartalmazzon... jdbc.drivers import java.sql.*; class DBTeszt { public static void main(string args[]) throws SQLException { Connection c = DriverManager.getConnection(args[0]);... javac DBTeszt.java java -classpath msql-jdbc-1-0.jar:. -Djdbc.drivers=com.imaginary.sql.msql.MsqlDriver DBTeszt jdbc:msql://localhost:1112/stockmarket ó T bb meghajto is bet lthet (Windows ; es UNIX : elv.) Kíl nb z adatba ziskezel k óegy programban t bb adatbazis is hasznalhato, akar t bb adatbaziskezel n keresztíl is óaz atteres egyik adatbaziskezel r l egy masikra viszonylag egyszeru óf leg, ha az SQL utasıtasokban megmaradunk a szabva nyos lehet segeknel ónagyon sokfele adatbaziskezel h z keszıtettek mar JDBC meghajto programot (lasd Java honlap) óvan egy JDBC-ODBC kapcsolo meghajto, amivel minden olyan AB-kezel hasznalhato, amihez van ODBC (Open Data Base Connectivity) interfesz Connection letrehozasa str = "jdbc:msql://localhost:1112/stockmarket"; Connection c = DriverManager.getConnection(str); jdbc:alprotokoll:alne v Peldaul. jdbc.odbc.object.stockmarket óa parameterkent atadott sztringet vegigkerdezi a regisztralt meghajto kto l. Az els t, amelyik tud vele mit kezdeni (alprotokoll), megbızza a munka val ókivalasztasi sorrend: el sz r a jdbc.drivers, utana az explicit bet lt tt osztalyok 4
Statement ósql utasıtasok vegrehajtasara Statement s = c.createstatement(); óvannak lekerdezesek es adatmanipulacio k ólekerdezes ResultSet rs = s.executequery ("select * from Stock"); óadatmanipula cio int sorok = s.executeupdate ("insert into Stock values ('ABC',90)"); ót bb eredmenyt ado SQL utasıtas vegrehajtasa: boolean vaneredmeny = s.execute("..."); ResultSet óeredmenytabla, lekerdezes eredmenye ResultSet rs = s.executequery ("select * from Stock"); óa sorait egymas utan feldolgozhatjuk while( rs.next() ){... ókezdetben a kurzor az els sor ele mutat óaz aktualis sor komponenseit kiszedhetjík String s = rs.getstring(1)); óegy Statement-hez egyszerre csak egy ResultSet lehet megnyitva Eredmenysorok feldolgozasa óaz aktualis sorbo l az oszlopok (komponensek) kiszedhet k a getxxx meto dusokkal String getstring(int oszlop) int getint(int oszlop) óaz oszlopok 1-t l szamozo dnak ólehet az oszlop szama helyett a nevet megadni ö kevesbbe hatekony óaz oszlopokat balro l jobbra kell vegigolvasni, es csak egyszer ResultSet a JDBC 2.0 szerint óaz eredmenytabla kurzorat el re is lehet mozgatni, lehet benne pozıcionalni ólehet mo dosıtani az eredmenytablat, es rajta keresztíl az adatbazist óbe lehet pl. allıtani, hogy mas SQL utasıtasok hatasa ne jelenjen meg a feldolgozas alatt allo eredmenyta bla ban Statement stmt = con.createstatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); Pozıciona la s es sor mo dosıta sa rs.absolute(5); rs.updatestring("nev", "Janis Joplin"); rs.updaterow(); ószkrollozhato es mo dosıthato ResultSet ójdbc 2.0 kell hozza óaz updatexxx meto dusok szaba lyai ugyanazok, mint a getxxx meto dusokei 5
Sor beszérasa es t rlese rs.movetoinsertrow(); rs.updatestring(1,"sting"); rs.updateint(2,35); rs.updateboolean(3,true); rs.insertrow(); rs.movetocurrentrow(); rs.deleterow(); Java tıpusok es JDBC tıpusok ógetstring, getint,... BIT, TINYINT, SHORTINT, INT, LONGINT ójava.math.bigdecimal - NUMERIC ógetasciistream - LONGVARCHAR ógetbinarystream - LONGVARBINARY, getcharacterstream ójava.sql.blob, java.sql.clob ójava.sql.date, Time, Timestamp PreparedStatement óha egy SQL utasıtast t bbsz r is vegre akarunk hajtani óel fordıtott SQL utasıtas ö Ha a meghajto ta mogatja az el fordıtast óhatekonyabb, mint t bbsz r egy Statement-et óparameterezhet ö setxxx meto dusok ö A parameter tıpusanak megfelel setxxx kell óa Statement leszarmazottja Pelda Alkalmazott[] beosztottak =... PreparedStatement s = c.preparestatement( "insert into Alkalmazott" + "(Nev, Fizetes, Id) values (?,?,?)" ); for(int i=0; i<beosztottak.length; i++){ s.setstring(1, beosztottak[i].getnev()); s.setint(2, beosztottak[i].getfizetes()); s.setint(3, 100*i) s.executeupdate(); Callable Statement ónem-sql utasıtasok, pl. tarolt eljarasok vegrehajta sa ra ójdbc elja ra shıva si escape-szekvencia {call <procedure-name>[<arg1>,<arg2>,...] {?= call <procedure-name>[<arg1>,...] ólehetnek bemeneti es kimeneti parameterei ö Es vegyes... ö A kimenetiek tıpusat regisztrani kell vegrehajtas el tt óa visszaadott eredmenyeeket (pl. ResultSet) el bb kell feldolgozni, mint a kimeneti parametereket ópreparedstatement leszarmazottja 6
CallableStatement s = c.preparecall ( "{call return_seats[?,?,?]" ); s.setstring(1, "MA-723"); s.registeroutparameter (2, java.sql.types.boolean); s.registeroutparameter (3, java.sql.types.integer); s.execute(); // eredmenyek feldolgozasa, ha vannak boolean dohanyzo = s.getboolean(2); int szabadhelyek = s.getint(3); Statement.execute() boolean tabla = s.execute("..."); int sorok = s.getupdatecount(); while ( tabla (sorok!= -1) ){ if(tabla){ ResultSet rs = s.getresultset(); // csinalunk rs-sel valamit else { // csinalunk sorok-kal valamit tabla = s.getmoreresults(); sorok = s.getupdatecount(); javax.sql - szabvanyos kiterjesztes ójndi - logikai nev az adatbazisok eleresehez ö fíggetlenseg az adatbazis nevet l es pontos eleresi Étvonalato l óadatbazis-kapcsolatok cache-elese ö a kapcsolat felepıtese nagyon id igenyes ójta - Java Transaction API hasznalata ö ketfa zisé protokoll tranzakcio kezeleshez óadattablak kezelese off-line T bbretegu (multi-tier) alkalmazasok óket retegu modell: a felhasznalo i interfesz az adatbazishoz kapcsolo dik óharom retegu modell: k zbeiktatunk egy szerveroldali programot ö a felhasznalo i felílet a halo zaton kapcsolo dik a szerverhez óhtml form (+szervlet), applet, program óhttp, TCP - UDP, RMI, CORBA ö a szerver az adatbazis(ok)kal tartja a kapcsolatot ö biztonsa g, megbızhato sag, rugalmassag, k nnyebb hasznalat, konfiguralhato sag Tranzakcio k ólogikailag sszetartozo adatbaziskezel utasıtasok egyítese óhajto djon vegre az egesz (vagy semmi) óveglegesıtes: commit, visszavonas: rollback ókonkurrens adatbaziskezeles eseten problemak: sorbarendezhet seg (serializability) ö Hatasban legyen olyan, mintha valamilyen sorrendbben egymas utan hajto dtak volna vegre ö Inkonzisztens adatok elkerílese ö Holtpont-veszely! 7
Tranzakcio k keszıtese óalapertelmezett: automatikus nyugtazas ö Minden SQL utasıtas befejez dese utan nyugtaz óvegrehajto dott, es nem ad vissza eredmenyt óaz utasıtast tartalmazo SQL objektmot Éjra vegrehajtjuk óeredmenytala utolso sorat is feldolgoztuk óaz eredmenytablat lezarjuk ómanualis nyugtazasi mo d ö setautocommit ö A programozo hıvja meg a commit es rollback meto dusokat Tranzakcio izola cio s szintek óa kapcsolathoz rendelhetjík (Connection) ósettransactionisolation ö TRANSSACTION_NONE: nincs tranz. kez. ö _READ_UNCOMMITED: olvasaskor mindig az aktualis erteket latjuk ö _READ_COMMITED: olvasaskor mindig a leguto bbi veglegesıtett eredmenyt latjuk ö _REPEATABLE_READ: a tranzakcio altal olvasott ertekek megegyeznek a kezdeti ertekkel ö _SERIALIZABLE: a tranzakcio ideje alatt az olvasott ertekeket mas tranzakcio k nem ırhatjak felíl Hibakezeles ósqlexception ö getmessage() ö SQLstate (X/OPEN SQLstate szabvany szerint) ö Hibako d (adatba ziskezel -specifikus ko d) ö Hivatkozas a k vetkez hibara (kiegeszıtesek) ósqlwarning ö Automatikusn lekezelik a JDBC meto dusok ö Az SQL-objektumokhoz lancolva, listaban ö getwarnings(), clearwarnings() DatabaseMetaData óaz adatbazis jellemz i ógetmetadata() ósql fogalmak adatbazisspecikifus megvalo sıtasai, annak korlatai ö getcatalogseparator(), getidentifierquotestring(), getmaxconnections(), getmaxcolumnsintable() óaz adatba ziskezel tuda sa ö supportsfulljoins(), supportsresultsetconcurrency() ö JDBC COMPLIANT ósupportscolumnaliasing(), supportssubqueriesinexists()... K tegelt (batch) vegrehajtas ógyorsabb adatmanipula cio s/definıcio s utasıtasok int[] sorok; Statement s = c.createstatement(); s.addbatch("insert into Nevek" + "values ('Lennon', 'McCartney')"); s.addbatch("insert into Nevek" + "values ('Sz renyi', 'Brody')"); sorok = s.executebatch(); 8