Adatbázis rendszerek II. V. előadás – JDBC Előadó: Barabás Péter Dátum: 2008. 10. 16.
JDBC
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
JDBC
2
JDBC--adatbázis interakció JDBC
JDBC
3
JDBC rétegei JAVA alkalmazás JDBC API JDBC menedzser JDBC meghajtó API JDBC Hálózati protokoll meghajtó
Nyilvános protokoll
JDBC-ODBC meghajtó
Specifikus meghajtó
ODBC meghajtó
Speciális adatbázis hozzáférési protokoll JDBC
4
JDBC 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
JDBC
5
JDBC szintjei
JDBC alap (Core) API ◦ java.sql.* csomag ◦ tartalmazza az adatbázis eléréséhez szükséges alapvető osztályokat
JDBC standard kiterjesztés (Extension) API javax.sql.* csomag további - haladó szintű – csomagok JTA API (Java Transakció API)
JDBC
6
Adatbázis alkalmazás modell Kétrétegű modell
JAVA alkalmazás
JDBC DBMS
Háromrétegű modell
Kliens JAVA alkalmazás
szolgáltató réteg (pl. j2ee szerver)
JDBC
JDBC DBMS
7
JDBC 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ő JDBC 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
JDBC
8
JDBC Driver típusok JDBC-ODBC átjáró (bridge) JDBC-hálózati protokoll JDBC-saját kliens API bridge JDBC saját Java API
JDBC
9
JDBC--ODBC bridge JDBC JAVA alkalmazás
JDBC driver
SQL parancs
Eredményhalmaz ODBC driver
Megfelelő protokoll
DBMS JDBC
10
JDBC--hálózati protokoll JDBC JAVA alkalmazás
JDBC driver
SQL parancs
Eredményhalmaz JDBC driver Köztes réteg
Megfelelő protokoll
DBMS JDBC
11
JDBC--saját API bridge JDBC JAVA alkalmazás
JDBC driver
SQL parancs
Eredményhalmaz DBMS saját API
Megfelelő protokoll
DBMS JDBC
12
JDBC--saját JAVA API JDBC JAVA alkalmazás
JDBC driver
SQL parancs DBMS protokollon
Eredményhalmaz DBMS protokollon
DBMS JDBC
13
JDBC osztályok
JDBC
14
JDBC kapcsolat felépítése
Megfelelő JDBC driver regisztrálása ◦ dinamikus, direkt betöltés Class.forName(JDBC driver class); v. DriverManager.registerDriver(JDBC 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:… JDBC
15
JDBC kapcsolat felépítése II.
DataSource interfész (JDBC 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 JDBC
16
JDBC 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”);
JDBC
17
JDBC 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); JDBC
18
JDBC 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 JDBC
19
JDBC – 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
JDBC
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
JDBC
21
Statement példák Statement stmt = Connection.createStatement(); ResultSet rs = stmt.executeQuery(”select * from auto”); int cnt = stmt.executeUpdate(”insert into auto values(‘aaa111’,’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’”);
JDBC
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 JDBC
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(?,?,?,?,?,?)”); JDBC
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() JDBC
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();
JDBC
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); JDBC
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 JDBC
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) JDBC
29
Eredmény 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);
JDBC
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()
JDBC
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
JDBC
32
Típusok
JDBC
33
Típusok II.
JDBC
34
Típusok III.
JDBC
35
Kapcsolat lezárása lezárása
Eredménytábla lezárása: ◦ ResultSet.close();
Statement lezárása: ◦ Statement.close();
Adatbáziskapcsolat lezárása: ◦ Connection.close();
JDBC
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(); JDBC
37
Hibakezelés try { … } catch (SQLException e) { … } catch (SQLWarning w) { … } JDBC
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( ); } }
JDBC
39
Köszönöm a figyelmet!
JDBC
40