Kapitel 7

Werbung
Kapitel 7
Java-Anbindung für objektrelationale
Datenbanken
Java und Datenbanken
JDBC
SQLJ
Lesestoff
Programmiersprache Java
l Java ist
–
–
–
–
–
objektorientiert (Klassen als Abstraktionskonzept)
einfach
n automatisierte Speicherverwaltung
n Verzicht auf Zeiger und Goto
robust und sicher
n strenge Typisierung
n Laufzeitüberpüfung von Zugriffen
interpretiert und dynamisch
architekturneutral und portabel
n Plattformunabhängiger Zwischencode (Bytecode)
n Programme sind ohne Änderungen ablauffähig unter Windows, Unix, ...
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-2
Java und Datenbanken
l Einsatz von Java
–
–
–
auf Client-Seite:
n DB-Anwendungen
auf Server-Seite:
n DB-Erweiterungen (benutzerdefinierte Prozeduren, Funktionen & Datentypen)
auf Middleware-Ebene:
n Anwendungslogik (JavaBeans)
l Anbindung Java - Datenbank
–
–
JDBC (Java Database Connectivity; Call-Level-Schnittstelle)
SQLJ (Embedded SQL; Java-Relational Database Technology)
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-3
Java und Datenbankanwendungen
Benutzerschnittstelle DB-Client
CORBA, HTTP, ...
Benutzerschnittstelle
DB-Client
Anwendungslogik
DB-Schnittstelle
DBMS-Protokoll
DB-Server
Anwendungslogik
JDBC,
SQLJ
DB
DB-Schnittstelle
AnwendungsServer
DBMS-Protokoll
DB
DB-Server
Benutzerdefinierte
Prozeduren, Funktionen
& Datentypen in Java
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-4
JDBC - Überblick
l Datenbankzugriffsschnittstelle für Java
–
–
–
–
abstrakt und datenbankneutral
vergleichbar mit ODBC
Low-Level-API: direkte Nutzung von SQL
Java-Package java.sql
l Klassen
–
–
–
–
DriverManager: Einstiegspunkt, Laden von Treibern
Connection: Datenbankverbindung
Statement: Ausführung von Anweisungen über eine Verbindung
ResultSet: verwaltet Ergebnisse einer Anfrage, Zugriff auf einzelne Spalten
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-5
Datenbankanbindung - Ablauf
l Aufbau einer Verbindung zur Datenbank
–
–
Angabe der Verbindungsinformationen
Auswahl und dynamisches Laden des Treibers
l Senden einer SQL-Anweisung
–
–
Definition der Anweisung
Belegung von Parametern
l Verarbeiten der Anfrageergebnisse
–
–
Navigation über Ergebnisrelation
Zugriff auf Spalten
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
DriverManager
getConnection()
Connection
createStatement()
Statement
executeQuery()
ResultSet
7-6
Verbindungsaufbau
l Treiber laden (2 Varianten)
Class.forName("com.company.DBDriver");
Oracle oracle.jdbc.driver.OracleDriver
DB2
COM.ibm.db2.jdbc.app.DB2Driver
Informix com.informix.jdbc.IfxDriver
DriverManager.registerDriver(new com.company.DBDriver());
l Verbindung herstellen
String url = "jdbc:subprotocol:datasource";
String user = "scott";
String passwd = "tiger";
Connection con = DriverManager.getConnection(url, user, passwd);
–
JDBC-URL spezifiziert
n Datenquelle/Datenbank
n Verbindungsmechanismus (Protokoll, Server-Host und Port)
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-7
Ausführung einer DB-Anfrage bzw. DB-Änderung
l Anweisungsobjekt (Statement) erzeugen
Statement stmt = con.createStatement();
l Anweisung ausführen
String queryStmt = "SELECT Name, Anschrift FROM Kunde";
ResultSet rset = stmt.executeQuery(queryStmt);
–
Klasse java.sql.Statement
n Ausführung von Anfragen (SELECT) mit executeQuery
n Ausführung von Änderungen (DELETE, INSERT, UPDATE) mit executeUpdate
(liefert Anzahl der betroffenen Tupel/Objekte)
String delStmt = "DELETE Kunde WHERE KNr = 1311";
int rows = stmt.executeUpdate(delStmt);
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-8
Ergebnisverarbeitung
l Navigation über Ergebnismenge (Cursor-Prinzip)
while (rset.next()) {
// Verarbeitung der einzelnen Tupel
...
}
l Zugriff auf Spaltenwerte über getXXX-Methoden
–
über Spaltenindex
String name = rset.getString(1);
–
über Spaltenname
String name = rset.getString("Name");
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-9
Lesestoff
Fehlerbehandlung
l Fehlerbehandlung mittels Exception-Mechanismus
l SQLException für alle SQL- und DBMS-Fehler
try {
// Aufruf von JDBC-Methoden
...
} catch (SQLException exc) {
System.out.println("SQLException: " + exc.getMessage());
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-10
Lesestoff
Transaktionssteuerung
l Methoden von Connection
–
–
commit()
rollback()
l Auto-Commit-Modus
–
–
–
implizites Commit nach jeder Anweisung
Transaktion besteht nur aus einer
Anweisung
Umschalten mittels
setAutoCommit(boolean)
l Transaktionsisolationsebenen
–
setzen mittels setTransactionLevel(int)
try {
// AutoCommit-Modus ausschalten
con.setAutoCommit(false);
// DML-Anweisungen
...
// COMMIT ausführen
con.commit();
} catch (SQLException exc) {
// Änderungen zurücknehmen
con.rollback();
}
TRANSACTION_NONE
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_READ_SERILIZABLE
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-11
Anfrageformen
l Statement
–
–
Basisklasse für alle Anweisungen
Verarbeitung einfacher SQL-Anweisungen ohne Parameter
l PreparedStatement
–
–
–
Kapselung einer vorkompilierten Anweisung
parametrisierbar
Verwendung: wiederholte Ausführung einer Anweisung (mit verschiedenen
Parametern)
l CallableStatement
–
Aufruf von gespeicherten Prozeduren mit Parametern
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-12
Vorübersetzte Anweisungen
l java.sql.PreparedStatement
–
–
Beschleunigung der Ausführung von Anweisungen durch Vorübersetzung und
wiederholten Aufruf mit verschiedenen Parametersätzen
l Anweisungsobjekt (PreparedStatement) erzeugen
String insStmt = "INSERT INTO Kunde VALUES (?, ?)";
PreparedStatement stmt = con.prepareStatement(insStmt);
Anweisungsparameter
durch "?" markiert
l Belegung der Parameter mittels setXXX-Methoden
stmt.setString(1, "George");
stmt.setFloat(2, 4500.00);
l Anweisung ausführen stmt.executeUpdate(insStmt);
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-13
Aufruf von gespeicherten Prozeduren
l java.sql.CallableStatement
–
Aufruf von gespeicherten Prozeduren (Stored Procedures)
l Anweisungsobjekt (CallableStatement) erzeugen und Parameter setzen
String callStmt = "{CALL TestProc(?, ?)}";
CallableStatement stmt = con.prepareCall(callStmt);
stmt.setInt(1, 42);
l Registrierung des SQL-Typs der OUT-Parameter & Auslesen der
Ergebniswerte mit getXXX-Methoden
stmt.registerOutParameter(2, java.sql.Types.FLOAT);
stmt.executeUpdate();
double res = stmt.getDouble(2);
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-14
Lesestoff
JDBC-Interfaces
ResultSet
executeQuery
executeUpdate
Statement
executeQuery
executeUpdate
getXXX
PreparedStatement
setXXX
Data Types
DriverManager
createStatement
getConnection
prepareStatement
Connection
prepareCall
getXXX
CallableStatement
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-15
Lesestoff
Neue Features in JDBC 2
l Core API - Bestandteil von Java 2
–
–
–
–
Scrollbare und änderbare ResultSets
Batch-Updates
SQL-99-Datentypen
Benutzerdefinierte Typabbildung
l Optional API
–
–
–
–
Nutzung von Namensdiensten (JNDI)
Connection Pooling
Verteilte Transationen
RowSets
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
// ARRAY
public Array ResultSet.getArray()
public void PreparedStatement.setArray()
public String Array.getBaseTypeName()
public Object Array.getArray()
// STRUCT
public Object ResultSet.getObject()
public void PreparedStatement.setObject()
public Object[] Struct.getAttributes()
public String Struct.getSQLTypeName()
// REF
public Ref ResultSet.getRef()
public void PreparedStatement.setRef()
public String Ref.getBaseTypeName()
// OBJECT
public Object ResultSet.getObject()
public void PreparedStatement.setObject()
public String Object.toString()
public Object Object.clone()
7-16
JDBC - Beispiel (in Oracle)
import java.sql.*;
import java.util.*;
class Kunden {
//
Lade
Oracle
Verbindung
zur
ORDB
//
Ladestatic
Oracle
JDBC
Treiberund
undstelle
stelle
Verbindung
zurDatenbank
Datenbank
ORDBher
her
public
voidJDBC
main Treiber
(String
args
[])
throws
SQLException
{
DriverManager
.registerDriver
oracle.jdbc.driver.
()); her
// Lade Oracle
JDBC Treiber(new
und stelle
Verbindung zurOracleDriver
Datenbank ORDB
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
Connection
con =
DriverManager.getConnection
("jdbc:oracle:oci8:@", "scott",
"tiger");
Connection
"scott",
"tiger");
Connectioncon
con=
= DriverManager.getConnection("jdbc:oracle:oci8:@",
DriverManager.getConnection("jdbc:oracle:oci8:@", "scott",
"tiger");
//
Erzeuge
und
führe
SQL
Anweisung
aus
////Erzeuge
aus& iteriere durch die Ergebnismenge
Erzeugeund
und führe
führe SQL-Anweisung
SQL-Anweisung aus
//
Iteriere
durch
die
Ergebnismenge
Statement
con.
createStatement();
Statement
stmt=
=
con.createStatement();
//
Iterierestmt
durch
die
Ergebnismenge
Statement
stmt
=
con.createStatement();
ResultSet
=stmt.
Anschrift,
Telefone
FROM
Kunde");
while
(rs.next())
{stmt.executeQuery("SELECT
ResultSet
rsrsrs=
Name,
Anschrift,
Telefone
FROM
Kunde");
while
(rs.next())
{ executeQuery("SELECTName,
ResultSet
=
stmt.executeQuery("SELECT
Name,
Anschrift,
Telefone
FROM
Kunde");
while
(rs.next())
{
Struct
a
=
(Struct)
rs.getObject(2);
Struct
Structa a=
=(Struct)
(Struct) rs.getObject(2);
rs.getObject(2);
Object
attrs
[]
=
a.getAttributes();
Object
attrs
[]
=
a.getAttributes();
attrsdie
[] Ergebnismenge
=
a.getAttributes();
//
Schliesse
//Object
Schliesse
die
Ergebnismenge
Array
t
=
rs.getArray(3);
Array
rs.
closet();
Array
t=
=rs.getArray(3);
rs.getArray(3);
rs.close();
System.out.println("Kundenname
:+" rs.getString(1));
+ rs.getString(1));
System.out.println("Kundenname:
"
System.out.println("Kundenname:
"
+
rs.getString(1));
//
Schliesse
die
Anweisung
System.out.println("Wohnort
: "+
attrs[3] + ", " + attrs[4]);
//
Schliesse
die
Anweisung
System.out.println("Wohnort:
"
+
attrs[3]
+
System.out.println("Telefon
" +(String)((Object[])t.getArray())[0].toString());
stmt.
close();
System.out.println("Wohnort:
" + :attrs[3]
+",",""+
+attrs[4]);
attrs[4]);
stmt.close();
}
System
.out.println("Telefon: ""+
getArray())[0].toString());
System.out.println("Telefon:
+(String)((Object[])t.
(String)((Object[])t.getArray())[0].toString());
//
Schliesse
die
Verbindung
//
Schliesse
die
Verbindung
rs.close(); stmt.close(); con.close();
// Schliessen aller Resourcen
}con.
}} close();
con.close();
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-17
SQLJ
l Standardisierte Java-DB-Schnittstelle
l Spezifikationen
–
Part 0: Embedded SQL für Java (ANSI-Standard; Object Language Binding)
n Statische Einbettung von SQL-Anweisungen in Java-Quelltext
–
Part 1: Java Stored Procedures (ANSI-Standard; seit September 1999)
n Im DB-Server gespeicherte Java-Prozeduren & Java-Funktionen
–
Part 2: Java-Klassen für benutzerdefinierte SQL-Datentypen
n Verwendung von Java-Klassen als SQL-Datentypen
l Oracle, IBM, Informix, Sybase, Tandem, Sun, Microsoft stehen dahinter
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-18
Embedded SQL für Java- Überblick
l Vorübersetzung des um SQLAnweisungen erweiterten JavaQuelltextes in „echten“ Java-Code
durch Translator sqlj
Java-Quelltext mit
eingebetteten SQL-Anweisungen
SQLJ-Translator
SQLJ- Java-Quelltext mit
JDBC-Aufrufen
Profil
l Überprüfung der SQL-Anweisungen
–
korrekte Syntax
–
Übereinstimmung der Anweisungen
mit DB-Schema
–
Typkompatibilität der für den
Datenaustausch genutzten Variablen
Java-Compiler
Java Byte-Code
Customizer
Syntax-Check
l Nutzung von JDBC-Treibern
DB
SQLJLaufzeitsystem
JDBC
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-19
SQLJ-Anweisungen
l SQL-Anweisungen
–
–
–
–
QL-, DML- und DDL-Anweisungen
Prozeduraufrufe
Funktionsaufrufe
Aufruf unbenannter SQL-Blöcke
#sql { Anweisung };
#sql { CALL Prozedur(Param) };
#sql r = { VALUES(Funktion(Param)) };
#sql { BEGIN ... END };
l Klassendefinitionen für
–
–
Iteratoren
Kontexte
#sql iterator IteratorKlasse(Typdefinitionsliste);
#sql context MyContext;
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-20
Lesestoff
Host-Variablen
l Variablen einer Host-Sprache (hier Java), die in SQL-Anweisungen
auftreten können
l Verwendung: Austausch von Daten zwischen Host-Sprache und SQL
l Zugriff auf Host-Variablen in SQLJ-Anweisungen mittels
Doppelpunktnotation :variable
l Beispiel:
String kname;
#sql { SELECT Name INTO :kname FROM Kunde WHERE KNr = 2322 };
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-21
Iteratoren
l Java-Objekte, die das Cursor-Konzept implementieren
l Formen:
–
Benannte Iteratoren
#sql iterator KundeIter(int KNr, String Name);
n Spaltenzugriff über Accessor-Methode mit dem Spaltennamen
n Iteration mittels Methode next()
–
Positionsiteratoren
#sql iterator KundePosIter(String);
n Spaltenzugriff über Position in der Anweisung
n Iteration mittels FETCH...INTO-Anweisung
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-22
Lesestoff
Benannte Iteratoren - Beispiel
// Deklaration eines benannten Iterators
#sql iterator KundeIter(int KNr, String Name);
// Definition eines Iteratorobjekts
KundeIter kunden;
// Ausführung einer SQL-Anweisung; Population des Iterators
#sql kunden = { SELECT KNr, Name FROM Kunde WHERE Name LIKE 'C%' };
// Iteration durch die Ergebnismenge; Spaltenzugriff mittels Accessor-Methoden
while (kunden.next()) {
System.out.println(kunden.KNr() + " " + kunden.Name();
}
// Iterator schliessen
kunden.close();
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-23
Lesestoff
Positionsiteratoren - Beispiel
// Deklaration eines Positionsiterators sowie einer Variablen
#sql iterator KundePosIter(String);
String kundenname;
// Definition eines Iteratorobjekts
KundePosIter kunden;
// Ausführung einer SQL-Anweisung; Population des Iterators
#sql kunden = { SELECT Name FROM Kunde WHERE Name LIKE 'C%' };
// Iteration durch die Ergebnismenge
while (true) {
#sql { FETCH :kunden INTO :kundenname }; // Hole nächsten Datensatz
if (kunden.endFetch()) break;
// Iterator am Ende?
System.out.println(kundenname);
}
// Iterator schliessen
kunden.close();
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-24
Lesestoff
Verbindungskontext
l Jede SQL-Anweisung wird mit einem Verbindungskontext assoziiert
–
Verbindung zur einer bestimmten DB mittels expliziten Verbindungskontext
#sql context KundeKontext;
String url = "jdbc:subprotocol:datasource";
String user = "scott";
String passwd = "tiger";
KundeKontext ctx = new KundeKontext(url, user, passwd, false)
–
Ausführung einer SQL-Anweisung in einem explizitem Verbindungskontext
#sql [ctx] { SQL-Anweisung };
–
Defaultkontext
ConnectionContext.getDefaultContext()
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-25
Lesestoff
Ausführungskontext
l Jede SQL-Anweisung wird in einem Ausführungskontext ausgeführt
–
Definition eines expliziten Ausfürhtungskontextes
ExecutionContext execCtx = new ExecutionContext()
–
Ausführung einer SQL-Anweisung in einem explizitem Verbindungskontext
#sql [execCtx] { SQL-Anweisung };
–
Defaultkontext
ConnectionContext.getExecutionContext()
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-26
Lesestoff
Verbindungsaufbau in Oracle
l Oracle stellt Connect-Methode bereit, die eine DB-Verbindung und einen
Default-Kontext aufbaut
–
Entspricht etwa
Connection con = DriverManager.getConnection(url, user, passwd);
DefaultContext ctx = new DefaultContext(con);
DefaultContext.setDefaultContext(ctx);
–
Aufruf der Connect-Methode
oracle.connect(url, user, passwd);
–
Alternativer Aufruf (Verbindungsparameter in connection.properties definiert)
oracle.connect(JavaKlasse.class, "connection.properties");
7-27
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
JPublisher - Automatische Generierung von Java-Wrappern
l Oracle-spezifische Konversion zwischen SQL- und Java-Typen
–
Für alle Typen werden Konstruktoren und weitere Methoden generiert, z.B.
n Objekttypen: getXXX() und setXXX()-Methoden für alle Attribute XXX
n Referenttypen: getValue() und setValue()-Methoden
n Kollektionstypen: getArray() und setArray()-Methoden, getElement() und
setElement()-Methoden
// types.in : Input-Datei für JPublisher
// TYPE SQL-Typ AS Java-Typ
TYPE TelefonArrayTyp AS TelefonArrayTyp
TYPE AdresseTyp AS AdresseTyp
TYPE TeilTyp AS TeilTyp
JPublisher
TelefonArrayTyp.java
AdresseTyp.sqlj
AdresseTypRef.java
TeilTyp.sqlj
TeilTeilRef.java
Aufruf des JPublishers: jpub -input=types.in -user=scott/tiger
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-28
SQLJ - Beispiel (Objekt- & Arraybehandlung in Oracle)
import java.sql.SQLException;
import oracle.sqlj.runtime.Oracle; // Package für Oracle SQLJ Support
//
Iterator
//
Benannter
Iterator
//Benannter
Benannter
Iterator
#sql iterator KundenIter(String Name, AdresseTyp Anschrift, TelefonArrayTyp Telefone);
#sql
iterator
elefone);
#sql
iterator
KundenIter(StringName,
Name,AdresseTyp
AdresseTypAnschrift,
Anschrift,TelefonArrayTyp
TelefonArrayTypTTelefone);
class
Kunden
{ KundenIter(String
public static void main (String args []) throws SQLException {
// Stelle DB-Verbindung her: URL, USER und PASSWD aus Datei connect.properties
Oracle.connect(Kunden.class, "connect.properties");
//
//
Erzeuge
Iterator
//Erzeuge
ErzeugeIterator
Iterator, führe eingebettete SQL-Anweisung aus & iteriere durch die Ergebnismenge
//
F
ühre
eingebettete
-Anweisung aus
kunden; SQL
SQL-Anweisung
aus
//KundenIter
Führe eingebettete
KundenIter
kunden;
KundenIter
kunden;
//
Iteriere
durch
dieSELECT
Ergebnismenge
//
Iteriere
durch
Ergebnismenge
#sql
kunden
=
SELECT
Name,
Telefone
FROM
Kunde
}; };
#sql
kunden
=
Name,
Anschrift,
Telefone
FROM
Kunde
#sql
kunden
={{{die
SELECT
Name,Anschrift,
Anschrift,
Telefone
FROM
Kunde
};
while
(kunden.next())
{
while
next()) {{
while(kunden.
(kunden.next())
AdresseTyp
a
=
iter.Anschrift();
AdresseTyp
aa=
AdresseTyp
=iter.Anschrift();
iter.Anschrift();
System.out.println("Kundenname
iter.Name());
System
.
out
.
println
("Kundenname: ::" "+
+
iter.Name());
System.out.println("Kundenname
"
+
iter.Name());
System.out.println("Wohnort
:
"
+
a.getOrt()
++
", "",+" +
a.getLand());
System
.
out
.
println
("Wohnort
:
"
+
a.
getOrt()
getLand());
System.out.println("Wohnort : :" +
" +iter.Telefone().getArray()[0]);
a.getOrt()
+ ", " +a.a.getLand());
System.out.println("Telefon
System.out.println("Telefon
:: ""+
getArray()[0]);
+iter.Telefone().
iter.Telefone().getArray()[0]);
} System.out.println("Telefon
}}}
}
7-29
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
Vergleich
l JDBC:
–
–
–
–
Call-Level-Schnittstelle
Dynamisches SQL
Fehlererkennung zur Laufzeit
Hohe Flexibilität
l SQLJ:
–
–
–
–
Embedded-SQL-Lösung
Statisches SQL
Fehlererkennung zur Compile-Zeit
Kompakte Notation
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
// JDBC
int n;
Statement stmt = con.prepareStatement
(“INSERT INTO Tabelle VALUES (?)”);
stmt.setInt(1,n);
stmt.execute ();
stmt.close();
// SQLJ
int n;
#sql{INSERT INTO Tabelle VALUES (:n)};
7-30
SQLJ / JDBC - Interoperation
l Innerhalb einer Anwendung können SQLJ- und JDBC-Anweisungen
interoperieren
–
Erzeugen eines SQLJ-Iterators aus einem JDBC-Resultset
ResultSet rs= ...;
#sql iterator iter { ... };
#sql iter = { CAST :rs };
–
Erzeugen eines JDBC-Resultsets aus einem SQLJ-Iterator
#sql iterator iter { ... };
#sql iter = { ... };
ResultSet rs= iter.getResultSet();
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-31
Java im DB-Server
l Java-VM als Teil des DBMS
–
–
Plattformneutrale, sichere Umgebung zur Ausführung prozeduraler Anweisungen
Erweiterung des DBMS (Java Prozeduren, Funktionen & Typen)
l SQLJ
–
Part 1: Benutzerdefinierte Java-Prozeduren & Java-Funktionen
n im DB-Server gespeichert und ausgeführt
–
Part 2: Benutzerdefinierte Java-Klassen als SQL-Datentypen
n als Spaltentypen von Datenbankrelationen verwendbar
–
Ablauf:
n Implementierung → Installation → Registrierung → Nutzung
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-32
Gespeicherte Prozeduren & Funktionen
l Vorteile
–
–
–
–
Reduzierung der
Netzwerkbelastung
Performance-Verbesserung
Zentrale Verwaltung
n Sicherheit
n Backup
n Recovery
n Administration
Unabhängigkeit vom
Client-System
Anwendung
Anwendung
...
Anwendung
... CALL Java-Prozedur
... CALL Java-Prozedur
DB-Client
...
CALL Java-Prozedur
...
...
DB
Java-VM
Java-Prozedur
DB-Server
Methode
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-33
Gespeicherte Prozeduren & Funktionen: Ablauf
l Implementierung
–
–
–
als statische Methode einer Klasse
Default-Verbindung zur Datenbank
DB-Zugriff über JDBC oder SQLJ
l Installation im Server als JAR-Archiv
CALL sqlj.install_jar('file:~/routines.jar', 'routines_jar', 0);
// Ersetzen bzw. Löschen eines JAR-Archivs
CALL sqlj.replace_jar('file:~/routines.jar', 'routines_jar');
CALL sqlj.remove_jar('routines_jar');
–
in Oracle8i spezielle Werkzeuge: loadjava, dropjava
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-34
Gespeicherte Prozeduren & Funktionen: Ablauf (Forts.)
l Registrierung
–
Festlegung des Names, der Parameter und der Zuordnung zur Java-Methode
CREATE PROCEDURE GehaltErhoehen(MNr INTEGER, Betrag DECIMAL)
EXTERNAL NAME 'routines_jar:Routines.GehaltErhoehen(int, double)'
LANGUAGE JAVA
PARAMETER STYLE JAVA;
–
über Deployment-Deskriptor (siehe nächste Folie)
l Aufruf
–
–
–
über JDBC, SQLJ, andere API
in Anfragen bzw. DML-Operationen
durch Trigger
// Aufruf einer Java-Prozedur ist
// nicht unterscheidbar von einem
// Aufruf einer SQL-Prozedur
CALL Gehalt(3443, 1250.50);
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-35
Lesestoff
Registrierung über Deployment-Deskriptoren
l Deployment-Deskriptor
–
–
Textdatei mit SQL-Anweisungen, die beim Installieren bzw. Entfernen eines
JAR-Archivs ausgeführt werden
Zusammen mit den Klassendateien im JAR-Archiv gespeichert
SQLActions[] = {
"BEGIN INSTALL
CREATE PROCEDURE GehaltErhoehen(MNr INTEGER, Betrag DECIMAL)
EXTERNAL NAME 'routines_jar:Routines.GehaltErhoehen(int, double)'
LANGUAGE JAVA
PARAMETER STYLE JAVA;
END INSTALL",
"BEGIN REMOVE
DROP PROCEDURE GehaltErhoehen(INTEGER, DECIMAL);
END REMOVE"
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-36
Java-SQL-Datentypen
l Verwendung von Java-Klassen als SQL-Datentypen
–
–
Installation von Java-Klassen im DB-Server
Unterstützung in Sybase, Informix
l Benutzerdefinierter SQL-Datentyp
–
Klasse mit Attributen und Methoden
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-37
Java-SQL-Datentypen: Implementierung
l Klasse mit Schnittstelle java.io.Serializable
l Attribute zur Repräsentation von SQL-Daten als public definiert
l Zur Ausgabe: Definition der Methode toString
l Beispiel:
public class AdresseTyp implements java.io.Serializable {
public String Strasse;
public int Nr;
public int PLZ;
public String Ort;
public String Land;
public AdresseTyp() { Strasse = Ort = Land = ""; Nr = PLZ = 0; }
...
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-38
Java-SQL-Datentypen: Installation & Registrierung
l Installation von Java-Klassen im DB-Server als JAR-Archiv
CALL sqlj.install_jar('file:~/adresse.jar', 'adr_jar', 0);
l Registrierung über
erweitere Form von CREATE TYPE (Zuordnung der Klasse, Attribute & Methoden)
CREATE TYPE AdresseTyp
EXTERNAL NAME 'adr_jar:AdresseTyp'
LANGUAGE JAVA
(PLZ INTEGER EXTERNAL NAME 'PLZ',
METHOD AdresseTyp() RETURNS AdresseTyp EXTERNAL NAME 'AdresseTyp',
...);
–
vordefinierte Prozeduren (wie in Informix)
EXECUTE PROCEDURE sqlj.setUDTExtName(SQL-Typname, Java-Klassenname);
–
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-39
Java-SQL-Datentypen: Nutzung
l Verwendung des Java-Datentyps als Attributtyp
CREATE TABLE Kunde (
Name
VARCHAR(30),
Anschrift
AdresseTyp
);
l Initialisierung durch Konstruktor
INSERT INTO Kunde (Name, Anschrift) VALUES ('Joe', AdresseTyp());
l Zugriff auf Attribute und Methoden mittels SQL-99-Syntax
SELECT Anschrift.PLZ, Anschrift.Ort FROM Kunde;
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-40
Lesestoff
Anhang
JDBC - Beispiele
SQLJ - Beispiele
JDBC - Beispiel (in Oracle)
Lesestoff
import java.sql.*;
class SelectKunde {
public static void main (String args []) throws SQLException {
try {
// Lade Oracle JDBC Treiber und stelle Verbindung zur Datenbank ORDB her
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@ordb", "scott", "tiger");
// Erzeuge und führe SQL-Anweisung aus
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT k.Name, k.Anschrift.Ort FROM Kunde k");
// Iteriere durch die Ergebnismenge und gebe Namen und Wohnort aus
while (rs.next()) System.out.println(rs.getString(1) + " wohnt in " + rs.getString(2));
rs.close();
// Schliesse die Ergebnismenge
stmt.close();
// Schliesse die Anweisung
con.close();
// Schliesse die Verbindung
} catch (SQLException exc) {
System.out.println(exc); // Fehlerbehandlung
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-42
JDBC - Arraybehandlung (in Oracle)
Lesestoff
import java.sql.*;
import oracle.sql.*;
// Package für Oracle Object Support
public class SelectTelefonArray {
public static void main (String args[]) throws Exception {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@ordb", "scott", "tiger");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT Telefone FROM Kunde WHERE Telefone IS NOT NULL");
showResultSet(rs); //Funktion, die alle Elemente der Arrays anzeigt
String elements[] = { "0041-1-2332223", "0090-633-23232" }; // Erzeuge neues ARRAY-Objekt
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("TELEFONARRAYTYP", con);
ARRAY newArray = new ARRAY(desc, con, elements);
PreparedStatement ps = con.prepareStatement("UPDATE Kunde SET Telefone = ? WHERE Name = ?");
((OraclePreparedStatement)ps).setARRAY(1, newArray);
((OraclePreparedStatement)ps).setString(2, "Joe");
ps.execute(); // Führe Update aus
rs.close(); ps.close(); stmt.close(); con.close();
} // Methode main ... weiter auf der nächsten Folie
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-43
Lesestoff
JDBC - Arraybehandlung (Forts.)
public static void showResultSet(ResultSet rs) throws SQLException {
int line = 0;
while (rs.next()) {
line++;
// Zugriff auf Array-Informationen
ARRAY array = ((OracleResultSet)rs).getARRAY(1);
System.out.println ("Array ist vom Typ " + array.getSQLTypeName() +
" und hat die Laenge "+ array.length());
// Zugriff auf Array-Elemente
String[] values = (String[]) array.getArray();
for (int i=0; i<values.length; i++) {
String value = (String) values[i];
System.out.println(">> Telefon " + i + " = " + value);
}
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-44
JDBC - Objektbehandlung (in Oracle)
Lesestoff
import java.sql.*;
import oracle.sql.*;
public class KundeObject {
public static void main (String args []) throws Exception {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@ordb", "scott", "tiger");
Statement stmt = con.createStatement();
Object [] a = new Object [5]; // Erzeuge ein Adresse-Objekt
a[0] = "Rheinallee"; a[1] = "69"; a[2] = "8008"; a[3] = "Zurich"; a[4] = "CH";
StructDescriptor addressDesc = StructDescriptor.createDescriptor("ADRESSETYP", con);
STRUCT anschriftStruct = new STRUCT(addressDesc, con, adr);
PreparedStatement ps = con.prepareStatement("UPDATE Kunde SET Anschrift= ? WHERE Name= ?");
ps.setObject(1, anschriftStruct); ps.setString(2, "Joe");
ps.execute(); // Führe Update aus
ResultSet rs = stmt.executeQuery("SELECT Anschrift FROM Kunde WHERE Anschrift IS NOT NULL");
showResultSet(rs); // Zeige alle Anschriften der Tabelle Kunde
rs.close(); rs.close(); stmt.close(); con.close();
} // Methode main ... weiter auf der nächsten Folie
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-45
Lesestoff
JDBC - Objektbehandlung (Forts.)
public static void showResultSet(ResultSet rs) throws SQLException {
while (rs.next()) {
STRUCT adresse= (STRUCT)rs.getObject(1);
Object adresseAttribute [] = adresse.getAttributes();
System.out.println("Strasse: "
+ adresseAttribute[0]);
System.out.println("Nr: "
+ adresseAttribute[1]);
System.out.println("PLZ: "
+ adresseAttribute[2]);
System.out.println("Ort: "
+ adresseAttribute[3]);
System.out.println("Land: "
+ adresseAttribute[4]);
System.out.println();
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-46
JDBC - Referenzbehandlung (in Oracle)
Lesestoff
import java.sql.*;
import oracle.sql.*;
public class TeilRef {
public static void main (String args []) throws Exception {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection con = DriverManager.getConnection("jdbc:oracle:oci8:@ordb", "scott", "tiger");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery ("SELECT REF(t) FROM Teil t");
REF ref; STRUCT teil; Object a[];
// Variablendeklarationen
while (rs.next()){
// Iteration ueber alle Objektreferenzen
ref = (REF) rs.getObject(1);
// Zuweisung an Referenzvariable
teil = (STRUCT) ref.getValue();
// Zuweisung des Objektwertes
a = teil.getAttributes();
// Extraktion der Objektattribute
System.out.println("Nr: " + a[0], " Bezeichnung: " + a[1], " Farbe: " + a[2], " Oberteil: " + a[3]);
if (((REF) a[3]) != null) {
// Ausgabe Nr und Bezeichnung des referenzierten Oberteils
a = ((STRUCT) ((REF) a[3]).getValue()).getAttributes();
System.out.println ("Oberteil Nr = " + a[0] + " Bezeichnung = " + a[1]);
}
}
rs.close(); stmt.close(); con.close();
}
}
7-47
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
SQLJ - Beispiel (in Oracle)
Lesestoff
import java.sql.SQLException;
import oracle.sqlj.runtime.Oracle; // Package für SQLJ Support
#sql iterator KundeIter(String Name, String Ort); // benannter Iterator
class SelectKunde {
public static void main (String args []) throws SQLException {
try {
// Stelle DB-Verbindung her: URL, USER und PASSWD aus Datei connect.properties
Oracle.connect(SelectKunde.class, "connect.properties");
// Definition eines Iteratorobjekts
KundeIter kunden;
// Führe eingebettete SQL-Anweisung aus
#sql kunden = { SELECT k.Name AS Name, k.Anschrift.Ort AS Ort FROM Kunde k };
// Iteriere durch die Ergebnismenge und gebe Namen und Wohnort aus
while (kunden.next()) System.out.println (kunden.Name() + " wohnt in " + kunden.Ort());
} catch (SQLException exc) {
System.out.println(exc); // Fehlerbehandlung
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-48
SQLJ - Arraybehandlung (in Oracle)
Lesestoff
import java.sql.SQLException;
import oracle.sqlj.runtime.Oracle;
#sql iterator KundeIter(String Name, TelefonArrayTyp Telefone);
// benannter Iterator
class SelectTelefonArray {
public static void main (String args []) throws SQLException {
try {
// Stelle DB-Verbindung her: URL, USER und PASSWD aus Datei connect.properties
Oracle.connect(SelectTelefonArray.class, "connect.properties");
// Erzeuge neues ARRAY-Objekt und ändere arraywertiges Attribut
String telefone [] = { "0041-1-2332223", "0090-633-2323299" };
TelefonArrayTyp array = new TelefonArrayTyp(telefone);
#sql { UPDATE Kunde SET Telefone = :array WHERE Name = 'Joe' };
// Definition eines Iteratorobjekts
KundeIter iter;
// Führe eingebettete SQL-Anweisung aus
#sql iter = { SELECT Name, Telefone FROM Kunde WHERE Telefone IS NOT NULL };
// weiter auf der nächten Folie
7-49
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
SQLJ - Arraybehandlung (Forts.)
Lesestoff
//Zeige alle Elemente der Arrays an
while (iter.next()) {
array = iter.Telefone();
// Zugriff auf Array-Informationen
System.out.println("Kunde = " + iter.Name());
// Zugriff auf einzelne Array-Elemente
String[] values = array.getArray();
for (int i=0; i<values.length; i++)
System.out.println((i+1) + ". Telefon = " + values[i]);
} // while
} catch (SQLException exc) {
System.out.println(exc);
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
// Fehlerbehandlung
7-50
SQLJ - Objektbehandlung (in Oracle)
Lesestoff
import java.sql.SQLException;
import oracle.sqlj.runtime.Oracle;
#sql iterator AdressIter(AdresseTyp Anschrift);
// benannter Iterator
class KundeObject {
public static void main (String args []) throws SQLException {
try {
// Stelle DB-Verbindung her: URL, USER und PASSWD aus Datei connect.properties
Oracle.connect(KundeObject.class, "connect.properties");
// Erzeuge Anschriftkomponenten
String strasse = "Rheinallee";
int nr
= 69;
int plz
= 8008;
String ort
= "Zurich";
String land
= "CH";
// Führe eingebettete SQL-Anweisung aus
#sql { UPDATE Kunde SET Anschrift = AdresseTyp(:strasse, :nr, :plz, :ort, :land)
WHERE Name = 'Joe' };
// weiter auf der nächsten Folie
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
SQLJ - Objektbehandlung (Forts.)
7-51
Lesestoff
// Definition eines Iteratorobjekts
AdressIter iter;
// Führe eingebettete SQL-Anweisung aus und iteriere über die Ergebnismenge
#sql iter = { SELECT Anschrift FROM Kunde WHERE Anschrift IS NOT NULL };
while (iter.next()) {
AdresseTyp anschrift = iter.Anschrift();
System.out.println("Strasse: "
+ anschrift.getStrasse()); // JPublisher generierte
System.out.println("Nr: "
+ anschrift.getNr());
// get-Methoden zum
System.out.println("PLZ: "
+ anschrift.getPlz());
// Zugriff auf
System.out.println("Ort: "
+ anschrift.getOrt());
// Objektattribute
System.out.println("Land: "
+ anschrift.getLand());
} // while
} catch (SQLException exc) {
System.out.println(exc); // Fehlerbehandlung
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-52
SQLJ - Referenzbehandlung (in Oracle)
Lesestoff
import java.sql.SQLException;
import oracle.sqlj.runtime.Oracle;
#sql iterator TeilRefIter(TeilTypRef Teil);
// benannter Iterator
class SelectTeilRef {
public static void main (String args []) throws SQLException {
try {
// Stelle DB-Verbindung her: URL, USER und PASSWD aus Datei connect.properties
Oracle.connect(SelectTeilRef.class, "connect.properties");
// Definition eines Iteratorobjekts
TeilRefIter iter;
// Führe eingebettete SQL-Anweisung aus und iteriere über die Ergebnismenge
#sql iter = { SELECT REF(t) AS Teil FROM Teil t };
// weiter auf der nächsten Folie
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
SQLJ - Referenzbehandlung (in Oracle)
7-53
Lesestoff
while (iter.next()) {
TeilTypRef ttr = iter.Teil();
TeilTyp t = ttr.getValue();
// JPublisher generierte get-Methode
System.out.println("Nr: " + t.getNr() + ", Bezeichnung: "+ t.getBezeichnung()+
" Farbe: " + t.getFarbe() ", Oberteil: " + t.getIstteilvon());
if (t.getIstteilvon() != null) {
// Ausgabe Nr und Bezeichnung des Oberteils
t = t.getIstteilvon().getValue();
System.out.println ("Oberteil Nr = " + t.getNr() +
", Bezeichnung = " + t.getBezeichnung());
}
} // while
} catch (SQLException exc) {
System.out.println(exc);
// Fehlerbehandlung
}
}
}
Vorlesung "Objektrelationale, erweiterbare Datenbanken - WS 2001/2002 (Dr. C. Türker)
7-54
Herunterladen