56
Programrendszerek Fejlesztése 7/4 1

Programrendszerek Fejlesztése

  • Upload
    bary

  • View
    39

  • Download
    0

Embed Size (px)

DESCRIPTION

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 - PowerPoint PPT Presentation

Citation preview

Page 1: Programrendszerek Fejlesztése

Programrendszerek Fejlesztése

7/4

1

Page 2: Programrendszerek Fejlesztése

Az előző előadás tartalma:

2

XPath XSLT XSD

Page 3: Programrendszerek Fejlesztése

Irodalom

3

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/20

04summerWestminster/Presentations/java%20server%20faces.pdf

Page 4: Programrendszerek Fejlesztése

A mai előadás tartalma

4

JDBC Típusai Kapcsolat típusok Statement objektumok RecordSet Tranzakciók

Hibernate

Page 5: Programrendszerek Fejlesztése

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)

Page 6: Programrendszerek Fejlesztése

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

Page 7: Programrendszerek Fejlesztése

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

Page 8: Programrendszerek Fejlesztése

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

Page 9: Programrendszerek Fejlesztése

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

Page 10: Programrendszerek Fejlesztése

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

KliensKözépső réteg

(Servlet, EJBean)Adatbázis

SzeverJDBC

http, RMI, …

Page 11: Programrendszerek Fejlesztése

11

Three-tier Model

Page 12: Programrendszerek Fejlesztése

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

Page 13: Programrendszerek Fejlesztése

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

Page 14: Programrendszerek Fejlesztése

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)

Page 15: Programrendszerek Fejlesztése

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());} }}

Page 16: Programrendszerek Fejlesztése

16

JDBC kapcsolat felépítés III.

Connection Pooling ConnectionPoolDataSourc

e 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)

Page 17: Programrendszerek Fejlesztése

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");

Page 18: Programrendszerek Fejlesztése

18

JDBC objektumok

Page 19: Programrendszerek Fejlesztése

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");

Page 20: Programrendszerek Fejlesztése

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

Page 21: Programrendszerek Fejlesztése

21

Metadata – Általános információk

getURL getUserName getDatabaseProductVersion, getDriverMajorVersion

and getDriverMinorVersion getSchemaTerm, getCatalogTerm and

getProcedureTerm nullsAreSortedHigh and nullsAreSortedLow usesLocalFiles and usesLocalFilePerTable getSQLKeywords

Page 22: Programrendszerek Fejlesztése

22

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

Page 23: Programrendszerek Fejlesztése

23

Metadata - korlátok getMaxRowSize getMaxStatementLength getMaxTablesInSelect getMaxConnections getMaxCharLiteralLength getMaxColumnsInTable

Page 24: Programrendszerek Fejlesztése

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 érkezikConnection con = DriverManager.getConnection(url, "sunny", ""); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

Page 25: Programrendszerek Fejlesztése

25

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

Page 26: Programrendszerek Fejlesztése

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...}

Page 27: Programrendszerek Fejlesztése

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

Page 28: Programrendszerek Fejlesztése

28

PéldaConnection 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

Page 29: Programrendszerek Fejlesztése

29

Statement pooling

Page 30: Programrendszerek Fejlesztése

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

Page 31: Programrendszerek Fejlesztése

31

Példa INCallableStatement 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();

Page 32: Programrendszerek Fejlesztése

32

Példa OUTCallableStatement 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);

Page 33: Programrendszerek Fejlesztése

33

Példa INOUTCallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}");

cstmt.setByte(1, (byte)25);

cstmt.registerOutParameter(1, java.sql.Types.TINYINT);

cstmt.executeUpdate();

byte x = cstmt.getByte(1);

Page 34: Programrendszerek Fejlesztése

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

Page 35: Programrendszerek Fejlesztése

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);

Page 36: Programrendszerek Fejlesztése

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”);

Page 37: Programrendszerek Fejlesztése

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();

Page 38: Programrendszerek Fejlesztése

38

Result set insert, deleters.first();rs.deleteRow();

rs.moveToInsertRow();rs.updateObject(1, myArray);rs.updateInt(2, 3857);rs.updateString(3, "Mysteries");rs.insertRow();rs.first();

Page 39: Programrendszerek Fejlesztése

39

Példajava.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);

}

Page 40: Programrendszerek Fejlesztése

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()) {

. . .}

Page 41: Programrendszerek Fejlesztése

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

Page 42: Programrendszerek Fejlesztése

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

Page 43: Programrendszerek Fejlesztése

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_UNCO

MMITTED); 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)

Page 44: Programrendszerek Fejlesztése

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

Page 45: Programrendszerek Fejlesztése

45

Tranzakciók: SavePointDatabaseMetaData.supportsSavepoints

Statement stmt = conn.createStatement();int rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) VALUES " +"(’FIRST’)");// set savepointSavepoint svpt1 = conn.setSavepoint("SAVEPOINT_1");rows = stmt.executeUpdate("INSERT INTO TAB1 (COL1) " +"VALUES (’SECOND’)");...conn.rollback(svpt1);...conn.commit();

Connection.releaseSavepoint

Page 46: Programrendszerek Fejlesztése

46

Elosztott tranzakciók

Tranzakció kezelő (JTA) JDBC meghajtó:

XADataSource XAConnection XAResource

Alkalmazás szerver

Page 47: Programrendszerek Fejlesztése

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;...

Page 48: Programrendszerek Fejlesztése

48

PéldaContext 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();

Page 49: Programrendszerek Fejlesztése

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

Page 50: Programrendszerek Fejlesztése

50

Példajavax.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);

Page 51: Programrendszerek Fejlesztése

51

Nagy adatmennyiség JDBC 3.0 SQL 3

getXXX, setXXX Array BLOB (Binary Large Object) CLOB (Character Large Object)

getCharacterStream

JDBC 1.0 LONGVARBINARY LONGVARCHAR

getBinaryStream getAsciiStream getUnicodeStream

locator

Page 52: Programrendszerek Fejlesztése

52

Példajava.sql.Statement stmt = con.createStatement();ResultSet rs = stmt.executeQuery("SELECT x FROM

Table2");// Now retrieve the column 1 results in 4 K chunks:byte [] buff = new byte[4096];while (rs.next()) {

Clob cdata = rs. getCLOB(1);java.io.InputStream fin = cdata.getAsciiStream();for (;;) {

int size = fin.read(buff);if (size == -1) {

break;}output.write(buff, 0, size);

}}

Page 53: Programrendszerek Fejlesztése

53

NULL érték típustól függően kezeli

null - karakterekre 0 - számokra false - boolean

int n = rs.getInt(3);boolean b = rs.wasNull();

Page 54: Programrendszerek Fejlesztése

54

Kötegelt utasítások

növeli a teljesítményt addBatch()

// turn off autocommitcon.setAutoCommit(false);Statement stmt = con.createStatement();stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe

Jones')");stmt.addBatch("INSERT INTO departments VALUES (260,

'Shoe')");stmt.addBatch("INSERT INTO emp_dept VALUES (1000,

260)");// submit a batch of update commands for executionint[] updateCounts = stmt.executeBatch();

Page 55: Programrendszerek Fejlesztése

55

Függvények használata getNumericFunctions() getStringFunctions() getSystemFunctions() getTimeDateFunctions() supportsConvert() getXXXFunctions()

UPDATE myTableSET circularVal = squared * { fn PI() }...

Page 56: Programrendszerek Fejlesztése

A következő előadás tartalma

56

Hibernate