1 / 56

Programrendszerek Fejlesztése

Programrendszerek Fejlesztése. 7 / 4. Az előző előadás tartalma:. XPath XSLT XSD. Irodalom. http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/ http://java.sun.com/j2ee/1.4/docs/tutorial/doc/J2EETutorial.pdf Hans Bergsten: Java Server Pages

bary
Télécharger la présentation

Programrendszerek Fejlesztése

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programrendszerek Fejlesztése 7/4

  2. Az előző előadás tartalma: • XPath • XSLT • XSD

  3. Irodalom • http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/ • http://java.sun.com/j2ee/1.4/docs/tutorial/doc/J2EETutorial.pdf • Hans Bergsten: Java Server Pages • http://web.princeton.edu/sites/isapps/jasig/2004summerWestminster/Presentations/java%20server%20faces.pdf

  4. A mai előadás tartalma • JDBC • Típusai • Kapcsolat típusok • Statement objektumok • RecordSet • Tranzakciók • Hibernate

  5. SQL, ODBC • SQL (Sturctured Query Language) • adatbázis, tábla, sor , oszlop • relációs adatbázis • lekérdezés • módosító lekérdezés • nézet • ODBC (Open Database Connectivity) • X/Open SQL CLI • C nyelven alapuló interfész • egységes felületet biztosít az adatbázisokhoz • a gyártók saját meghajtókat írnak • PC szabvány (csaknem ipari szabvány)

  6. JDBC • A Java platform legfontosabb összetevője • Platform és szállító független • Egy egyszerű Java API a programozók számára • JDBC meghajtó menedzser • Gyártó specifikus meghajtók mellyel az egyes gyártók optimalizálhatják a kapcsolatot • Hasonló megoldás mint a Microsoft igen sikeres ODBC megoldása (C nyelv) • Az adatok titkosítása az szállító meghajtó feladata

  7. JDBC • JDBC 1.0 • SQL 92 • egyszerű hívásszintű interfész • JDBC 2.0 • sokkal összetettebb funkciók, alkalmazásszerverek • connection pooling • distributed transaction • JDBC 3.0 • SQL 99

  8. JDBC meghajtók • JDBC-ODBC bridge plus ODBC driver • JDBC-t ODBC-re alakítja • az ODBC meghajtó kommunikál az adatbázissal • JDBC/ODBC bridge • nem támogatja a JDBC2-t • az ODBC-t kell beállítanunk • nem ajánlott a haszálata • Native-API partly-Java driver • a meghajtó részben Java nyelven részben más nyelven íródott • platform specifikus • JDBC-Net pure Java driver • egyszerű Java kliens könyvtár mely adatbázis független hálózati protokollon keresztül kommunikál egy szerver komponenssel mely ezt továbbítja az adatbázisnak • Native-protocol pure Java driver • egyszerű Java könyvtár mely közvetlenül az adatbázissal kommunikál

  9. Miért nem ODBC • Bonyolult • Kevés utasítás, bonyolult szintaxis • C specifikus, Pointer függő • Kevésbé biztonságos, nehezebben telepíthető mint a JDBC

  10. Használata • Használható • Java alkalmazásokban • Applet-ekben • csak a szerverrel tud kapcsolatot létesíteni • Három, vagy több rétegű alkalmazásokban http, RMI, … Adatbázis Szever Kliens Középső réteg (Servlet, EJBean) JDBC

  11. Three-tier Model

  12. JDBC installálása • PostgreSQL • pgjdbc2.jar ->…\lib\ext • postmaster –i • pg_hba.conf • CLASSPATH • windows: • http://www.ejip.net/faq/postgresql_win_setup_faq.jsp

  13. JDBC kapcsolat felépítés I. • Meghajtó betöltése: • try { Class.forName("org.postgresql.Driver"); } catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage()); } • java -Djdbc.drivers=org.postgresql.Driver Teszt • Adatbázis címzése: • jdbc:<alprotokoll>:<adatbázis hivatkozás> • jdbc:odbc://teszt.com:5000;UID=scott;PWD=tiger • jdbc:postgresql://160.114.36.248/teszt

  14. JDBC kapcsolat felépítés II. • Kapcsolat objektum: • Connection con; • con = DriverManager.getConnection(url, "Rendszergazda", ”x"); • Kifejezés: • Statement stmt; • stmt = con.createStatement(); • stmt.close(); • con.close(); • kilépéskor le kell zárnunk minden kapcsolatot !! (a szemétgyűjtő nem tudja megtenni helyettünk a statemenet-et igen)

  15. Példa: import java.sql.*; public class Teszt { public static void main(String args[]) { String url = "jdbc:postgresql://160.114.36.248/teszt"; Connection con; String createString; createString = "create table Teszt1 (COF_NAME VARCHAR(32), " + "SUP_ID INTEGER, PRICE FLOAT, SALES INTEGER, " + "TOTAL INTEGER)"; Statement stmt; try {Class.forName("org.postgresql.Driver");} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage());} try { con = DriverManager.getConnection(url, "Rendszergazda", "Alert"); stmt = con.createStatement(); stmt.executeUpdate(createString); stmt.close(); con.close(); } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage());} } }

  16. JDBC kapcsolat felépítés III. • Connection Pooling • ConnectionPoolDataSource interfész • 1:X kapcsolat • fizikai kapcsolatok helyett logikai kapcsolatok • a kliens nem érzékel semmit • Alkalmazás szerver biztosítja ezt a funkciót (Tomcat is)

  17. Példa com.acme.jdbc.ConnectionPoolDS cpds = new com.acme.jdbc.ConnectionPoolDS(); cpds.setServerName(“bookserver”); cpds.setDatabaseName(“booklist”); cpds.setPortNumber(9040); cpds.setDescription(“Connection pooling for bookserver”); Context ctx = new InitialContext(); ctx.bind(“jdbc/pool/bookserver_pool”, cpds); com.acme.appserver.PooledDataSource ds = new com.acme.appserver.PooledDataSource(); ds.setDescription(“Datasource with connection pooling”); ds.setDataSourceName(“jdbc/pool/bookserver_pool”); Context ctx = new InitialContext(); ctx.bind(“jdbc/bookserver”, ds); Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(" jdbc/bookserver"); Connection con = ds.getConnection("user", "pwd");

  18. JDBC objektumok

  19. Connection • Egy kapcsolatot jelent az adatbázissal • Egy alkalmazásnak egy-vagy több kapcsolat objektuma lehet, egy-vagy több adatbázissal • Connection.getMetaData • DatabaseMetaData, információ az adatbázisról • DriverManager.getConnection(URL) • a DriverManager megpróbál egy megfelelő meghajtót keresni az URL-ben szereplő adatbázishoz • DataSource ds.getConnection("user", "pwd");

  20. Metadata • DatabaseMetaData dbmd = con.getMetaData(); • kb. 150 metódust használhatunk • a legtöbb resultset objektumot ad vissza • sok metódus bonyolult névvel rendelkezik, célszerű olyan metódusokat használni melyek ezeket megadják

  21. Metadata – Általános információk • getURL • getUserName • getDatabaseProductVersion, getDriverMajorVersion and • getDriverMinorVersion • getSchemaTerm, getCatalogTerm and getProcedureTerm • nullsAreSortedHigh and nullsAreSortedLow • usesLocalFiles and usesLocalFilePerTable • getSQLKeywords

  22. Metadata-Lehetőségek • supportsAlterTableWithDropColumn • supportsBatchUpdates • supportsTableCorrelationNames • supportsPositionedDelete • supportsFullOuterJoins • supportsStoredProcedures • supportsMixedCaseQuotedIdentifiers • supportsANSI92EntryLevelSQL • supportsCoreSQLGrammar

  23. Metadata - korlátok • getMaxRowSize • getMaxStatementLength • getMaxTablesInSelect • getMaxConnections • getMaxCharLiteralLength • getMaxColumnsInTable

  24. Statement • paraméter nélküli kifejezések • egyszerű SQL kifejezések létrehozására használandó • executeQuery ( • egyszerű lekérdezés Select * from t • executeUpdate • INSERT • UPDATE • DELETE • CREATE TABLE • DROP TABLE • a visszatérési értéke egy integer mely az érintett sorok számát adja meg egyébként 0 • execute • olyan esetekben használják amikor több mint egy válasz érkezik Connection con = DriverManager.getConnection(url, "sunny", ""); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

  25. Példa: Execute Statement stmt = conn.createStatement(); boolean b = stmt.execute(sql); if (b == true) { // b is true if a ResultSet is returned ResultSet rs; rs = stmt.getResultSet(); while (rs.next()) { ... } } else { // b is false if an update count is returned int rows = stmt.getUpdateCount(); if (rows > 0) { ... } }

  26. Automatikusan Generált Kulcsok • Statement.RETURN_GENERATEDKEYS • getGeneratedKeys(); Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate("INSERT INTO ORDERS " + "(ISBN, CUSTOMERID) " + "VALUES (195123018, ’BILLG’)", Statement.RETURN_GENERATED_KEYS); ResultSet rs = stmt.getGeneratedKeys(); boolean b = rs.next(); if (b == true) { // retrieve the new key value ... }

  27. Prepared Statement • a Statement alosztálya • előre fordított SQL kifejezések • egy-vagy több paramétere lehet (IN) • több metódust használhatunk az IN paraméterek beállítására • sokkal hatékonyabb lehet mint a Statement objektum (előre fordított) • gyakran használt kifejezések létrehozására használandó • többször futtatható, a beállított paraméterek megmaradnak

  28. Példa Connection con = DriverManager.getConnection( "jdbc:my_subprotocol:my_subname"); con.setTransactionIsolation(TRANSACTION_READ_COMMITTED); PreparedStatement pstmt = con.prepareStatement( "SELECT EMP_NO, SALARY FROM EMPLOYEES WHERE EMP_NO = ?", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); pstmt.setFetchSize(25); pstmt.setString(1, "1000010"); ResultSet rs3 = pstmt.executeQuery(); pstmt.setString(1, "Hi"); for (int i = 0; i < 10; i++) { pstmt.setInt(2, i); int rowCount = pstmt.executeUpdate(); } • setNull

  29. Statement pooling

  30. Callable Statement • segítségével SQL tárolt eljárásokat futathatunk • supportsStoredProcedures() • getProcedures() • {? = call procedure_name[(?, ?, ...)]} • IN paraméterek • OUT paraméterek • regisztrálni kell • nincs külön lehetőség nagy adatok kezelésére • INOUT paraméterek

  31. Példa IN CallableStatement cstmt = con.prepareCall( "{call updatePrices(?, ?)}"); cstmt.setString(1, "Colombian"); cstmt.setFloat(2, 8.49f); cstmt.addBatch(); cstmt.setString(1, "Colombian_Decaf"); cstmt.setFloat(2, 9.49f); cstmt.addBatch(); int [] updateCounts = cstmt.executeBatch();

  32. Példa OUT CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.registerOutParameter(2, java.sql.Types.DECIMAL); ResultSet rs = cstmt.executeQuery(); // . . . byte x = cstmt.getByte(1); java.math.BigDecimal n = cstmt.getBigDecimal(2);

  33. Példa INOUT CallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}"); cstmt.setByte(1, (byte)25); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x = cstmt.getByte(1);

  34. Result Set • Az előző három objektum eredménye • Alapesetben nem írható és nem görgethető (csak egyszer lehet rajta végigmenni) • A JDBC 2.0 API ezeket lehetővé teszi • Nem minden meghajtó képes erre (pl.: postgresql) • getXXX(név vagy sorszám) metódusok (select a, select * ) • getMetaData • updateRow(), insertRow(), deleteRow(), refreshRow() • JDBC 2.0 • previous • first • last • absolute • relative • afterLast • beforeFirst

  35. Meta Data: ResultSet rs = stmt.executeQuery(sqlString); ResultSetMetaData rsmd = rs.getMetaData(); int colType [] = new int[rsmd.getColumnCount()]; for (int idx = 0, int col = 1; idx < colType.length; idx++, col++) colType[idx] = rsmd.getColumnType(col);

  36. Result set (JDBC 3.0) • Kurzor: • TYPE_FORWARD_ONLY • TYPE_SCROLL_INSENSITIVE • TYPE_SCROLL_SENSITIVE • Párhuzamosság • CONCUR_READ_ONLY • CONCUR_UPDATABLE • Tarthatóság: • HOLD_CURSORS_OVER_COMMIT • CLOSE_CURSORS_OVER_COMMIT • Használata: Connection conn = ds.getConnection(user, passwd); Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); ResultSet rs = stmt.executeQuery(“select author, title, isbn from booklist”);

  37. Result set updateXXX • CONCUR_UPDATABLE • SQL parancsok nélül módosíthatjuk a rekordokat • akkor működnek ha : • van elsődleges kulcs • a lekérdezés nem tartalmaz JOIN ill. GROUP BY kifejezést int n = rs.getInt(3); // n=5 . . . rs.updateInt(3, 88); int n = rs.getInt(3); // n = 88 rs.absolute(4); rs.updateString(2, "321 Kasten"); rs.updateFloat(3, 10101.0f); rs.updateRow();

  38. Result set insert, delete rs.first(); rs.deleteRow(); rs.moveToInsertRow(); rs.updateObject(1, myArray); rs.updateInt(2, 3857); rs.updateString(3, "Mysteries"); rs.insertRow(); rs.first();

  39. Példa java.sql.Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (rs.next()) { int i = rs.getInt("a"); String s = rs.getString("b"); float f = rs.getFloat("c"); System.out.println("ROW = " + i + " " + s + " " + f); }

  40. 2. Példa rs.beforeFirst(); while (rs.next()) { System.out.println(rs.getString("EMP_NO") + " " + rs.getFloat("SALARY"); } ----------------------------------------------------------------- rs.afterLast(); while (rs.previous()) { System.out.println(rs.getString("EMP_NO") + " " + rs.getFloat("SALARY"); } ----------------------------------------------------------------- ResultSet rs = stmt.executeQuery( "SELECT LAST_NAME, FIRST_NAME FROM EMPLOYEES"); rs.last(); int numberOfRows = rs.getRow(); System.out.println("XYZ, Inc. has " + numberOfRows + " employees"); rs.beforeFirst(); while (next()) { . . . }

  41. Tranzakciók • bankbetét átutalás • A helyen csökken • B helyen növekszik • egy tranzakció egy vagy több kifejezést tartalmaz melyek csak együtt hajtódnak végre (egyébként visszaállítja az eredeti állapotot - rollback) • a kapcsolat objektum auto-commit módban van azaz minden egyes kifejezést külön külön hajt végre • ha ez le van tiltva akkor a tranzakció addig nem ér véget amíg a commit vagy rollback metódusokat meg nem hívják • a tranzakció kezdete az auto-commit mód letiltásával kezdődik • a JDBC 2.0 API segítségével elosztott tranzakciókat is végrehajthatunk • JDBC 3.0 SavePoint

  42. A tranzakciók elkülönítése • piszkos olvasás (dirty read) • a tranzakció írásai a commit esemény előtt is olvashatóak • azaz valaki olvashatja azt az adatot amit esetleg később visszavonnak (rollback) • a többi tranzakció nem konzisztens adatok alapján működhet • megismételhetetlen olvasás (nonrepeatable read) • A tranzakció olvas egy sort • B tranzakció megváltoztatja • A tranzakció újra olvassa ugyanazt a megváltozott sort • fantom olvasás (phantom read) • A tranzakció olvassa az összes sort amely a WHERE feltételben van • B tranzakció beilleszt egy sort amely ugyanennek a feltételnek fele meg • A tranzakció újraértékeli a kifejezést és beveszi a fantom sort is

  43. A tranzakciók elkülönítési szintjei • 5 szint: • TRANSACTION_NONE • nincs tranzakció kezelés • TRANSACTION_READ_UNCOMMITTED • a nem végleges módosítások láthatóak (dirty read, …) • TRANSACTION_READ_COMMITTED • csak a végleges adatok olvashatóak (nincs dirty read, de van másik kettő) • TRANSACTION_REPEATABLE_READ • a másik tranzakció nem is írhatja az A tranzakció által érintett sorokat (phantom még lehet) • TRANSACTION_SERIALIZABLE • minden problémát kiküszöböl • con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); • magasabb elkülönítés lassabb működés (sok zárolás, egymásra várnak …) • a fentiek természetesen adatbázis-kezelő függőek (MySQL – gyenge tranzakció kezelés)

  44. con.setAutoCommit( false ); bError = false; try { for( ... ) { if( bError ) { break; } stmt.executeUpdate( ... ); } if( bError ) { con.rollback(); } else { con.commit(); } } / catch ( SQLException SQLe) { con.rollback(); ... } // end catch catch ( Exception e) { con.rollback(); ... } // end catch

  45. Tranzakciók: SavePoint • DatabaseMetaData.supportsSavepoints Statement stmt = conn.createStatement(); int rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) VALUES " + "(’FIRST’)"); // set savepoint Savepoint svpt1 = conn.setSavepoint("SAVEPOINT_1"); rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) " + "VALUES (’SECOND’)"); ... conn.rollback(svpt1); ... conn.commit(); • Connection.releaseSavepoint

  46. Elosztott tranzakciók • Tranzakció kezelő (JTA) • JDBC meghajtó: • XADataSource • XAConnection • XAResource • Alkalmazás szerver

  47. XADataSource, XAConnection • javax.sql • XAConnection -> PooledConnection: public interface XAConnection extends PooledConnection { javax.transaction.xa.XAResource getXAResource() throws SQLException; } • XADataSource: public interface XADataSource { XAConnection getXAConnection() throws SQLException; XAConnection getXAConnection(String user, String password) throws SQLException; ...

  48. Példa Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(“jdbc/inventory”); Connection con = ds.getConnection(“myID”,“mypasswd”); // Assume xads is a driver’s implementation of XADataSource XADataSource xads = (XADataSource)ctx.lookup(“jdbc/xa/" + "inventory_xa”); // xacon implements XAConnection XAConnection xacon = xads.getXAConnection(“myID”, “mypasswd”); // Get a logical connection to pass back up to the application Connection con = xacon.getConnection();

  49. XAResource • JTA - X/Open Group XA interface • XAConnection.getXAResource – egy tranzakció lehet • Az alkalmazás szerver ezt adja át a tranzakció menedzsernek • Two phase commit • Fontosabb metódusok (xid): • start • end • prepare • commit • rollback

  50. Példa javax.transaction.xa.XAResource resourceA = XAConA.getXAResource(); javax.transaction.xa.XAResource resourceB = XAConB.getXAResource(); … resourceA.start(xid, javax.transaction.xa.TMNOFLAGS); resourceA.end(xid, javax.transaction.xa.TMSUCCESS); resourceB.start(xid, javax.transaction.xa.TMNOFLAGS); resourceB.end(xid, javax.transaction.xa.TMSUCCESS); … resourceA.prepare(xid); resourceB.prepare(xid); … resourceA.commit(xid, false); resourceB.commit(xid, false); … resourceA.rollback(xid); resourceB.rollback(xid);

More Related