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
Programrendszerek Fejlesztése
7/4
1
Az előző előadás tartalma:
2
XPath XSLT XSD
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
A mai előadás tartalma
4
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
KliensKözépső réteg
(Servlet, EJBean)Adatbázis
SzeverJDBC
http, RMI, …
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 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)
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 érkezikConnection con = DriverManager.getConnection(url, "sunny", ""); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");
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) {...}}
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é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
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 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();
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);
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);
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, deleters.first();rs.deleteRow();
rs.moveToInsertRow();rs.updateObject(1, myArray);rs.updateInt(2, 3857);rs.updateString(3, "Mysteries");rs.insertRow();rs.first();
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);
}
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_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)
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: 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
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é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();
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é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);
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
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);
}}
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();
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();
55
Függvények használata getNumericFunctions() getStringFunctions() getSystemFunctions() getTimeDateFunctions() supportsConvert() getXXXFunctions()
UPDATE myTableSET circularVal = squared * { fn PI() }...
A következő előadás tartalma
56
Hibernate