9.4.1 JDBC und Transaktionsmanagement

Werbung
9.4.1 JDBC und Transaktionsmanagement
Isolation Level und JDBC
•
Der Isolation Level kann für eine Connection explizit gesetzt werden. Unterstützt
ein Treiber den in der Methode setTransactionIsolation(level) übergebenen
Level nicht, so darf er eine restriktivere Ebene verwenden. Unterstützt er keine
restriktivere Ebene, so wird eine Ausnahme vom Typ SQLException erzeugt.
Isolation Level sollten nie innerhalb einer Transaktion, sondern stets nur zwischen
zwei Transaktionen geändert werden.
void
void setTransactionIsolation(int
setTransactionIsolation(int level)
level)
throws
throws SQLException;
SQLException;
Konstanten des Connection-Interfaces
TRANSACTION_NONE
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
-- Beispiel: Isolation Level Serializable wird für die gesamte Session gesetzt
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Schestag
Datenbanken II
Kapitel 9 / 30
9.4.1 weitere Connection-Methoden (JDBC)
Transaktionsverhalten der Datenbank durch Methoden des Interface Connection:
void commit( )
void rollback( )
void setAutoCommit(boolean autoCommit)
)
Nach dem Aufbau der Verbindung ist die Datenbank gemäß JDBC-Spezifikation
zunächst im Auto-Commit-Modus, d.h. jede einzelne Anweisung wird als eigene
Transaktion angesehen, die nach Ende des Kommandos automatisch bestätigt
wird (commit).
Eine Änderung kann erreicht werden durch Aufruf von setAutoCommit mit
Übergabe von false.
Danach müssen alle Transaktionen explizit durch Aufruf von commit bestätig
bzw. durch rollback zurückgesetzt werden.
Nach Abschluss einer Transaktion beginnt automatisch die nächste.
Schestag
Datenbanken II
Kapitel 9 / 31
9.4.1 ResultSetMetaData und DatabaseMetaData (JDBC)
Die Methode getMetaData des Interfaces ResultSet liefert ein Objekt vom Typ
ResultSetMetaData zur selektierten Datenmenge.
Dieses Objekt kapselt Meta-Informationen zur selektierten Datenmenge, z.B.
int getColumnCount( )
String getColumnName(int column)
String getTableName(int column)
int getColumnType(int column)
...
Anzahl der Spalten
Name einer Spalte
Name einer Tabelle
Datentyp einer Spalte
Die Methode getMetaData des Interfaces Connection liefert ein Objekt vom Typ
DatabaseMetaData zur aktiven Verbindung.
Dieses Objekt kapselt Meta-Informationen zur aktiven Verbindung, die in die folgenden
Kategorien unterteilt werden können:
I. Informationen zur Datenbank
III. Informationen zu Beschränkungen des Treibers
II. Informationen zu unterstützten Features
IV. Informationen aus dem Systemkatalog
Mit Hilfe der Methode supportTransactionIsolationLevel des DatabaseMetaData-Objektes kann
z.B. abgefragt werden, ob eine Datenbank einen bestimmten Isolation Level unterstützt oder nicht.
Schestag
Datenbanken II
Kapitel 9 / 32
9.4.2 JDBC – objektrelationale Konzepte
Sämtliche SQL:1999-Datentypen werden von JDBC 2 unterstützt:
BLOB, CLOB, ARRAY, STRUCT, REF und DISTINCT
Folgende (abstrakte) Interfaces sind im Paket java.sql definiert:
Die konkreten JDBC-Treiber müssen also geeignete Klassen
bereitstellen, die die jeweiligen Interfaces implementieren,
sodass Objekte mit den entsprechenden Interfaces in einem
JDBC-Programm erzeugt werden können.
JDBC 2 erweitert die Interfaces ResultSet, PreparedStatement
und CallableStatement um entsprechende get- und setMethoden.
vgl. 9 / 35
Im Hinblick auf die in Kapitel 8 vorgestellten OR-Datentypen ab
der Version 8 von Oracle wird im folgenden ausschließlich die
Verarbeitung von Array-, Struct- und Ref-Werten beschrieben.
Literatur: C. Türker. SQL:1999 & SQL:2003, Objektrelationales SQL, SQLJ & SQL/XML. dpunkt.verlag 2003
Schestag
Datenbanken II
Kapitel 9 / 33
9.4.2 JDBC – Benutzerdefinierte Typabbildung (1)
•
Das Mapping zwischen Java und SQL führt eine strukturelle Transformation
durch und berücksichtigt nicht die Besonderheiten benutzerdefinierter Typen. Die
in SQL definierten Methoden sind nicht in der Java-Umgebung verfügbar:
SQL> CREATE TYPE Typ_Kunde
AS OBJECT (
KNr
INTEGER,
Name
VARCHAR2(20),
Adresse
Typ_Adresse,
Telefon
Typ_Telefon,
Kontakt
Typ_Kontakt,
RefAuftrag Typ_AuftragTab,
MEMBER FUNCTION
Last_Bestellung RETURN date
);
/
SQL> ...
select a.column_value.anr
from t_kunde k,
table(k.RefAuftrag) a
where k.name = 'Schmidt';
...
Schestag
Datenbanken II
package oraJdbc;
import java.sql.*;
...
public class MyJdbc {
....
?
?
}
Kapitel 9 / 34
9.4.2 JDBC – Benutzerdefinierte Typabbildung (2)
•
•
•
•
Schestag
Die benutzerdefinierte Typabbildung, die JDBC 2 anbietet, ermöglicht eine flexible
Abbildung zwischen den Objekten der Datenbank und Objekten in der JavaAnwendung.
Die jeweiligen Transformationen werden in entsprechenden Klassen einmal
definiert und liegen dann gekapselt zur Wiederverwendung in beliebigen JavaAnwendungen vor.
Eine Java-Klasse, die einen SQL-Datentyp repräsentiert, muss das Interface
SQLData implementieren:
Interface SQLData
Der Austausch der Daten zwischen der Java-Anwendung und der Datenbank
erfolgt über Ein- und Ausgabedatenströme, die über die Interfaces SQLInput
und SQLOutput gelesen bzw. geschrieben werden können.
Datenbanken II
Kapitel 9 / 35
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Datenfluss (1)
•
Lesen der Instanz eines SQL-Datentyp von der Datenbank:
getObject()
SQLData
Schestag
... ruft vom Interface SQLData ...
readSQL(stream,typeName)
... die Methode readSQL() auf, um einen
Strom von Attributwerten in das Java-Objekt
einzulesen.
SQLInput
Das Einlesen erfolgt mit Hilfe des Interfaces
SQLInput, ...
readXXX()
•
Initiierung: der JDBC-Treiber erzeugt
ein Objekt der zugehörigen Java-Klasse,
... das eine entsprechende read-Methode zur
Verfügung stellt.
Bei geschachtelten strukturierten Datentypen werden die Attribute in einer Tiefensuchordnung
gelesen, d. h. ein Attribut wird vollständig vor dem nächsten Attribut gelesen.
Datenbanken II
Kapitel 9 / 36
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Datenfluss (2)
•
Schreiben eines Java-Objektes in die Datenbank:
setObject(i, value)
SQLData
... ruft vom Interface SQLData ...
writeSQL(stream)
... die Methode writeSQL() auf.
SQLOutput
writeXXX(column)
•
Schestag
Initiierung: der JDBC-Treiber ...
Das Schreiben erfolgt mit Hilfe des Interfaces
SQLOutput, ...
... das geeignete write-Methoden zur
Verfügung stellt.
Alle Attribute des Java-Objektes werden in derselben Reihenfolge in den Ausgabedatenstrom
geschrieben, wie sie in der Klassendefinition aufgelistet sind.
Datenbanken II
Kapitel 9 / 37
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Klassendeklaration (1)
•
Das Beispiel des object-types Typ_Kunde – Klassendeklaration:
package oracle10g;
public class TypKunde
implements SQLData {
SQL> CREATE TYPE Typ_Kunde
AS OBJECT (
KNr
INTEGER,
Name
VARCHAR2(20),
Adresse
Typ_Adresse,
Telefon
Typ_Telefon,
Kontakt
Typ_Kontakt,
RefAuftrag Typ_AuftragTab,
MEMBER FUNCTION
Last_Bestellung RETURN date
);
/
...
private
private
private
private
private
private
private
String sqlType;
int knr;
String name;
Struct s;
Array a1;
Array a2;
Array a3;
public String getSQLTpyeName(
throws SQLException {
return "SYSTEM.TYP_KUNDE");
... // weiter s. nächste Folie
Schestag
Datenbanken II
Kapitel 9 / 38
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Klassendeklaration (2)
•
Fortsetzung: Das Beispiel des object-types Typ_Kunde – Klassendeklaration:
... // Fortsetzung vorhergehende Folie: Klasse TypKunde
public void readSQL(SQLInput sqlIn, String typeName)
throws SQLException {
sqlType = typeName;
knr = sqlIn.readInt();
name = sqlIn.readString();
s1 = (Struct) sqlIn.readObject();
a1 = sqlIn.readArray();
a2 = sqlIn.readArray();
a3 = sqlIn.readArray();
}
public void writeSQL(SQLOutput sqlOut) throws SQLException {
sqlOut.writeInt(knr);
sqlOut.writeString(name);
sqlOut.writeStruct(s1);
sqlOut.writeArray(a1);
sqlOut.writeArray(a2);
sqlOut.writeArray(a3);
}
Schestag
Datenbanken II
Kapitel 9 / 39
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Mapping (1)
•
)
)
Um eine Beziehung zwischen dem SQL-Datentyp und der JavaKlassendeklaration herzustellen, wird die Klasse java.util.Map genutzt:
Mit Hilfe der put-Methode wird dem Namen des SQL-Datentyps (key) der Wert
des zugehörigen Java-Typs (value) zugeordnet.
Mit Hilfe der get-Methode wird für einen gegebenen SQL-Datentyp der zugehörige
Java-Typ zurückgeliefert.
key
SQL-Typ
myMap.put("SYSTEM.TYP_KUNDE“,
Class.forName(“oracle10g.TypKunde“)
myMap.get("SYSTEM.TYP_KUNDE“)
)
Schestag
value
Java-Typ
System.Typ_Kunde
TypKunde
...
...
Außerdem müssen benutzerdefinierte Typabbildungen für einen Verbindungskontext bekannt gemacht werden:
Map Connection.getTypeMap()
void Connection.setTypeMap(Map myMap)
Datenbanken II
Kapitel 9 / 40
9.4.2 JDBC – Benutzerdefinierte Typabbildung: Mapping (2)
Das Beispiel des object-types Typ_Kunde – Mapping:
...
// Registrierung der benutzerdefinierten Typabbildung
java.util.Map myMap = con.getTypeMap();
myMap.put("SYSTEM.TYP_KUNDE",
Class.forName("oracle10g.TypKunde");
...
// Ausführung einer SQL-Anfrage
Statement stmt = con.createStatement();
String sqlQuery = "SELECT *
FROM t_auftrag a
WHERE a.anr = 101";
ResultSet rs = stmt.executeQuery(sqlQuery);
rs.next();
CREATE TYPE Typ_Auftrag
AS OBJECT (
ANr
INTEGER,
Eingang DATE,
Bearb DATE,
RefKunde REF Typ_Kunde
);
/
...
CREATE TABLE T_Auftrag
OF Typ_Auftrag (
ANr primary key);
// 4. Spalte der Ergebniszeile lesen
Ref myRef = rs.getRef(4);
TypKunde kunde = (TypKunde) myRef.getObject(myMap);
...
// Kundenobjekt ändern und zurückschreiben in die Datenbank
kunde.name = "Schmitt";
myRef.setObject(kunde); ...}
Schestag
Datenbanken II
Kapitel 9 / 41
Herunterladen