Adatbázis rendszerek II. V. előadás Előadó: Barabás Péter Dátum: 2008. 10. 16. 1
Java DataBase Connectivity Gazdanyelv: JAVA SQLJ (beágyazott SQL) Kiindulópont: SQL-CLI (X/Open) Hasonló az ODBC-hez nyelvi eltérések: mutatók hiánya objektumorientáltság Java-ban íródott Megköveteli az ANSI SQL92 támogatást 2
-adatbázis interakció 3
rétegei JAVA alkalmazás API menedzser meghajtó API Hálózati protokoll meghajtó -ODBC meghajtó ODBC meghajtó Specifikus meghajtó Nyilvános protokoll Speciális adatbázis hozzáférési protokoll 4
szolgáltatásai összekapcsolódás a relációs adatbázissal SQL utasítások végrehajtása SQL lekérdezések eredményeinek feldolgozása 5
szintjei alap (Core) API java.sql.* csomag tartalmazza az adatbázis eléréséhez szükséges alapvető osztályokat standard kiterjesztés (Extension) API javax.sql.* csomag további - haladó szintű csomagok JTA API (Java Transakció API) 6
Adatbázis alkalmazás modell Kétrétegű modell JAVA alkalmazás DBMS Háromrétegű modell Kliens JAVA alkalmazás szolgáltató réteg (pl. j2ee szerver) DBMS 7
Driverek rengeteg driver található a piacon http://developers.sun.com/product/jdbc/drivers 221 driver található a Java egy interfész halmazt követel meg, melyet a gyártóknak meg kell írniuk a megvalósítások a különböző driverek a szükséges meghajtók beregisztrálása után az adatbázisok kezelése elérhetővé válik az alkalmazások számára 8
Driver típusok -ODBC átjáró (bridge) -hálózati protokoll -saját kliens API bridge saját Java API 9
-ODBC bridge JAVA alkalmazás driver SQL parancs Eredményhalmaz ODBC driver Megfelelő protokoll DBMS 10
-hálózati protokoll JAVA alkalmazás driver SQL parancs Eredményhalmaz driver Köztes réteg Megfelelő protokoll DBMS 11
-saját API bridge JAVA alkalmazás driver SQL parancs Eredményhalmaz DBMS saját API Megfelelő protokoll DBMS 12
-saját JAVA API JAVA alkalmazás driver SQL parancs DBMS protokollon Eredményhalmaz DBMS protokollon DBMS 13
osztályok 14
kapcsolat felépítése Megfelelő driver regisztrálása dinamikus, direkt betöltés Class.forName( driver class); v. DriverManager.registerDriver( driver class); Class.forName( oracle.jdbc.driver.oracledriver ); v. DriverManager.registerDriver(new oracle.jdbc.driver.oracledriver()); statikus betöltés induláskor jdbc.drivers rendszerparaméter beállítása jdbc.drivers=oracle.jdbc.driver.oracledriver: 15
kapcsolat felépítése II. DataSource interfész ( 2.0) gyártó specifikus OracleDataSource ods = new OracleDataSource(); előnyei: Connection pooling egy fizikai adatbázis kapcsolaton több logikai kapcsolat Connection caching logikai kapcsolatok csoportja, mely ugyanazon adatbázishoz és sémához kapcsolódik hatékonyabb adatbázis elérés köztes rétegben ideális (JSP, Servlet, EJB) hátrány: adatbázis-kezelő rendszerfüggő megvalósítás 16
kapcsolat felépítése III. Connection objektum létrehozása Connection c = DriverManager.getConnection(Adatbázis URL, user, pass); Adatbázis URL jdbc:alprotokoll:adatforrás leírása Connection conn = DriverManager.getConnection( jdbc:oracle:thin: @arrakis.iit.uni-miskolc.hu:1521:info, proba, proba ); 17
kapcsolat felépítése IV. DataSource interfész 1. fizikai kapcsolat definiálása OracleDataSource ods = new OracleDataSource(); ods.setdrivertype( thin ); ods.setservername( arrakis.iit.uni-miskolc.hu ); ods.setnetworkprotocol( tcp ); ods.setdatabasename( info ); ods.setportnumber(1521); ods.setuser( proba ); ods.setpassword( proba ); 2. JNDI név regisztrálása Context ctx = new InitialContext(); ctx.bind( jdbc/infodb,ods); 18
kapcsolat felépítése V. DataSource interfész 3. logikai kapcsolat létrehozása OracleDataSource oconn = (OracleDataSource)ctx.lookup( jdbc/infodb ); Connection conn = oconn.getconnection(); Tranzakció-kezelés beállítása Connection.setAutoCommit(boolean ertek); ertek: TRUE: minden DML után véglegesítés FALSE: COMMIT, ROLLBACK a programból 19
SQL parancs végrehajtás Interfészek: Statement egyszerű SQL parancsokhoz (statikus) PreparedStatement bemenő paraméterekkel rendelkező SQL parancsokhoz (kvázi-statikus, dinamikus) CallableStatement ki- és/vagy bemenő paraméterekkel rendelkező SQL parancsokhoz, tárolt SQL eljárásokhoz 20
Statement Létrehozás: Statement stmt = Connection.createStatement(); Végrehajtás: executequery( SQL parancs ): lekérdezésre használható ResultSet típusú objektumban adja vissza az eredményt executeupdate( SQL parancs ); DML vagy DDL utasítások esetén használható a megváltozott sorok számát adja vissza, DDL esetén nullát executeupdate( SQL parancs ); tetszöleges SQL utasítás végrehajtására, például tárolt eljárás hívására a visszaadott eredménynek több komponense is lehet 21
Statement példák Statement stmt = Connection.createStatement(); ResultSet rs = stmt.executequery( select * from auto ); int cnt = stmt.executeupdate( insert into auto values( aaa- 111, Opel, piros,5,1000000, 123456ab ) ); int cnt = stmt.executeupdate( update auto set ar=ar*1.2 ); int cnt = stmt.executeupdate( delete from auto where rsz= aaa-111 ); 22
SQL utasítások kötegelt feldolgozása Statement.addBatch( SQL parancs ); Statement.executeBatch(); eredmény: egésztömb Statement.clearBatch(); Megjegyzések: csak DML és DDL utasítások lehetnek kötegben sikeres végrehajtás a kötegpuffer törlődik hiba esetén: SQLException v. BatchUpdateException 23
PreparedStatement Előnyei: az SQL utasítás előfordítása megtörténik többszöri futtatás esetén gyorsabb lehet bemenő paramétere Létrehozása: Connection.prepareStatement( ); a bemenő paraméterek helyén? van az SQL parancsban PreparedStatement pstmt=conn.preparestatement( INSERT INTO auto VALUES(?,?,?,?,?,?) ); 24
PreparedStatement - paraméterek Paraméterek megadása végrehajtás előtt PreparedStatement.setXXX(pozíció, érték); pozíció: a paraméter poziciója (melyik? ) XXX : típus pstmt.setstring(1, aaa-111 ); pstmt.setstring(3, piros ); pstmt.setint(5,1000000); pstmt.setstring(2, Opel ); pstmt.setint(4,5); pstmt.setstring(6, 12345678ab ); Végrehajtás executequery(), executeupdate(), execute(), addbatch(), executebatch() 25
CallableStatement Tárolt függvények, eljárások hívása Létrehozása: Connection.prepareCall(utasítás); CallableStatement cs = conn.preparecall( { call eljárásnév(paraméterek)} ); CallableStatement cs = conn.preparecall( { call auto_felvitel(?,?,?,?,?,?} ); cs.setstring(1, aaa-111 ); cs.setstring(2, Opel ); cs.setstring(3, piros ); cs.setint(4,5); cs.setint(5,1000000); cs.setstring(6, 12345678ab ); cs.executequery(); 26
CallableStatement - paraméterek IN paraméterek hasonlóan a PreparedStatement-hez? az utasításban, setxxx fv. a beállításnál OUT paraméterek cs.registeroutparameter(pozicio, típus); cs.getxxx(pozicio); CallableStatement cs = Connection.prepareCall( {? = call getautokdb(?)} ); cs.registeroutparameter(1,java.sql.types.integer); cs.setstring(2, piros ); ResultSet rs = cs.executequery(); int x = rs.getint(1); 27
Eredmény feldolgozása Lekérdezés eredménye ResultSet objektumba kerül Statement.executeQuery( SQL utasítás ); v. Statement.getResultSet(); ResultSet rs = stmt.executequery( select * from auto ); ResultSet típusok: CLOSE_CURSORS_AT_COMMIT CONCUR_READ_ONLY CONCUR_UPDATEABLE FETCH_FORWARD FETCH_REVERSE FETCH_UNKNOWN HOLD_CURSORS_OVER_COMMIT TYPE_FORWARD_ONLY TYPE_SCROLL_INSENSITIVE TYPE_SCROLL_SENSITIVE 28
Eredmény feldolgozása II. Eredményhalmaz bejárása soronként (CURSOR): next() következő sor previous() előző sor last() utolsó sor first() első sor afterlast() eredménytábla vége után beforefirst() eredménytábla eleje elé absolute(pozíció) paraméterül megadott számú sor relative(pozíció) aktuálishoz képest +pozíciódik sor (!negatív is lehet) 29
Eredmény feldolgozása III. Érték kiolvasása egy sor esetén: getxxx(oszlopindex); v. getxxx(oszlopnév); XXX: típus String cím = rs.getstring( SZIN ); Érték módosítása: updatexxx(oszlopnév, érték); XXX: típus String cím = rs.updateint( KOR,10); 30
Eredmény feldolgozása IV. Sor törlése: deleterow(); Sor beszúrása: insertrow(), movetoinsertrow() Változások érvényesítése az adatbázisban updaterow() 31
Eredmény információk ResultSetMetaData objektum ResultSetMetaData meta = rs.getmetadata(); Fontosabb információk: getcolumncount() mezők száma getcolumnname(i) i. mező neve getcolumntype(i) i. mező típusa gettablename(i) az i.-dik mező táblája 32
Típusok 33
Típusok II. 34
Típusok III. 35
Kapcsolat lezárása Eredménytábla lezárása: ResultSet.close(); Statement lezárása: Statement.close(); Adatbáziskapcsolat lezárása: Connection.close(); 36
Hibakezelés - hibaforrások kapcsolat létrehozási hiba SQL utasítás feldolgozási, végrehajtási hiba jogosultság, privilégium hibák hálózati hibák SQLException getnextexception(); getsqlstate(); geterrorcode(); SQLWarning printwarnings(sqlwarning warn); getnextwarning(); 37
Hibakezelés try { } catch (SQLException e) { } catch (SQLWarning w) { } 38
Példa hibakezelésre try { // forráskód } catch (SQLException e) { while(e!= null) { System.out.println("\nSQL Exception:"); System.out.println(e.getMessage( )); System.out.println("ANSI-92 SQL State: " + e.getsqlstate( )); System.out.println("Vendor Error Code: " + e.geterrorcode( )); e = e.getnextexception( ); } } 39
Köszönöm a figyelmet! 40