Java, XML und Oracle Database 10g – What`s new?

Werbung
Java, XML und Oracle Database 10g – What's new?
Carsten Czarski
Oracle Deutschland GmbH
München
Schlüsselworte
Java, JDBC, Anwendungsentwicklung, Web Services, XML, XML Schema Evolution, XML
Zeichensatz
Zusammenfassung
Oracle 10g steht im Zeichen des Grid Computing. Daher liegen die Entwicklungsschwerpunkte
bei der Optimierung der Cluster-Fähigkeiten und der Vereinfachung der Administration.
Im Gegensatz zu Oracle8, Oracle8i und Oracle9i wird mit Oracle10g kein neues Paradigma für
die Anwendungsentwicklung eingeführt. Entwickler, die sich mit Oracle10g beschäftigen, finden
jedoch viele Einzelverbesserungen und Erweiterungen zu bereits vorhandener Funktionalität vor.
Dieser Artikel beschäftigt sich mit den Neuerungen im Java- und XML-Umfeld. Der erste
Abschnitt widmet sich dem JDBC Treiber, der für den Java-Entwickler von besonderem Interesse
ist. Die Laufzeitumgebung für Java (JVM), die seit Oracle8i in die Datenbank integriert ist, steht
im Mittelpunkt des zweiten Abschnittes. Insbesondere die neue Möglichkeit, externe Web
Services aus der Datenbank heraus ansprechen zu können, wird hier ausführlich dargestellt.
Der letzte Abschnitt beschäftigt sich mit den Neuerungen hinsichtlich der nativen Unterstützung
von XML-Dokumenten in der Oracle-Datenbank
JDBC
Die JDBC Spezifikation trägt derzeit die Versionsnummer 3.01. JDBC 3.0 ist Bestandteil von
Java 1.4 und wird auch Bestandteil von J2EE 1.4 sein. Einige Anforderungen von JDBC 3.0
wurden bereits in die Oracle9i JDBC-Treiber (9.2.0) implementiert. Dazu gehören die
Unterstützung für Savepoints oder das Umschalten zwischen lokalen und globalen Transaktionen
im XA-Umfeld.
Diese Unterstützung wird mit Oracle10g weiter vervollständigt. Im folgenden sind die
wichtigsten Neuerungen beschrieben.
Named Parameter
Bislang erlaubte der JDBC-Standard beim Aufruf von gespeicherten Prozeduren, Funktionen
oder SQL-Kommandos nur positional binding. Dies entspricht den Konventionen von Java oder
auch C bzw. C++ und bedeutet, dass die übergebenen Parameter nach Ihrer Position zugeordnet
werden.
Statement.setString(1, “Max Mustermann”);
Named binding bedeutet, dass Parameter anhand Ihres Namens übergeben werden können, bei
einem INSERT Befehl also anhand des Namens der Tabellenspalte.
Statement.setString(“NAME”, “Max Mustermann”);
Diese Art der Parameterübergabe ist PL/SQL-Entwicklern bekannt.
begin
anyFunction(
name_parameter => ‘Max Mustermann’,
alter_parameter=> 50
);
end;
Named Binding ist insbesondere dann von Vorteil, wenn sich die Spalten einer Tabelle oder die
Parameter einer gespeicherten Prozedur ändern. Die Aufrufe dieser Prozeduren oder Funktionen
müssen dann meist nicht angepasst werden.
JDBC Connection Cache
Im J2EE-Umfeld ist es üblich, Connection-Pooling zu nutzen. Eine J2EE-Komponente entnimmt
Datenbankverbindungen nur für kurze Zeit aus dem Pool und gibt sie nach Gebrauch sofort
wieder zurück.
1
Ausführliche Informationen zu JDBC 3.0 können auf der Internet Seite von Sun
http://java.sun.com/products/jdbc/download.html#corespec30 gefunden werden.
unter
Bislang mussten alle Datenbankverbindungen in einem JDBC Connection-Pool unter dem
gleichen Benutzerkonto an der gleichen Datenbank angemeldet sein. Der Connection Cache in
Oracle10g erlaubt es, Datenbankverbindungen in ein- und demselben Connection-Pool sowohl
unter verschiedenen Benutzerkonten als auch zu verschiedenen Datenbanken herzustellen.
Dies ist insbesondere beim Betrieb von Oracle Real Application Cluster (RAC) wichtig. Der
Connection-Pool kann Verbindungen zu allen Knoten im Cluster enthalten und die Last
automatisch auf alle Knoten verteilen. Wenn der Connection-Pool nicht auf den
zwischenzeitlichen Absturz eines Knotens reagieren würde, würde das zur Auslieferung
ungültiger Datenbankverbindungen an die Anwendung führen.
Fast Connection Failover verhindert dies. Beim Absturz eines Clusterknotens wird mittels
Oracle Process Monitoring and Notification (opmn) eine Nachricht an den Connection-Pool
gesendet. Daraufhin werden die Verbindungen zu diesem Clusterknoten ungültig; der
Connection-Pool verteilt die Last auf die verbleibenden Knoten.
Der Connection-Pool reagiert auch auf das Wiederanlaufen des abgestürzten Knotens. In diesem
Fall werden die Datenbankverbindungen und damit die Last automatisch neu über alle Knoten
verteilt.
Fast Connection Failover bezieht sich jedoch nur auf Datenbankverbindungen im ConnectionPool, die gerade nicht in Benutzung sind. Wird die Datenbankverbindung gerade verwendet,
während der Knoten abstützt, führt dies zu einer Fehlermeldung (SQLException). Die
Anwendung sollte in diesem Fall eine neue Datenbankverbindung aus dem Connection-Pool
holen. Fast Connection Failover basiert auf der bereits beschriebenen Tatsache, dass
Datenbankverbindungen im J2EE-Umfeld nur für kurze Zeit aus dem Pool entnommen werden.
Homeless OCI Install
Die Nutzung des JDBC OCI Treibers hat sich mit Oracle10g stark vereinfacht. Da der OCI
Treiber auf den Bibliotheken des Oracle Call Interface (OCI) aufsetzt, war bislang zumindest die
Installation der Oracle Client-Software erforderlich.
Im Unterverzeichnis ezclient im ORACLE_HOME der Oracle10g-Software befindet sich das
Oracle Call Interface vollständig und ohne weitere Abhängigkeiten. Wenn diese Dateien sich in
den Umgebungsvariablen LD_LIBRARY_PATH bzw. PATH wiederfinden, kann das OCI oder
der JDBC OCI Treiber ohne weitere Abhängigkeiten genutzt werden. Ein einfaches Kopieren der
Bibliotheksdateien reicht daher zur Installation des OCI aus.
JDBC Web RowSet
JDBC Web RowSet ist eine Implementierung des JSR-1142. Es stellt eine API zur Verfügung, die
aus der Ergebnismenge eines SELECT-Kommandos (ResultSet) oder einer anderen Datenquelle
ein XML-Dokument erstellt. Das folgende Codebeispiel zeigt, wie – ausgehend von einem
JDBC ResultSet – mit dem JDBC Web RowSet ein XML Dokument erzeugt und ausgegeben
wird.
import oracle.jdbc.rowset.OracleWebRowSet;
:
:
ResultSet rs = statement.executeQuery(“select ... from ...”);
OracleWebRowSet west = new OracleWebRowSet();
wset.populate(rset);
wset.writeXml(new PrintWriter(System.out));
:
Diese Funktionalität ist noch nicht Bestandteil des JDBC-Standards. Daher befindet sie sich in
einer eigenen Java-Bibliothek. Nach Installation der Datenbank ist diese unter
$ORACLE_HOME/jdbc/lib/ocrs12.jar zu finden.
Datenbankinterne JVM
Die Java-Laufzeitumgebung in der Datenbank wurde weiterentwickelt und unterstützt nun den
aktuellen Stand 1.4. Damit werden Funktionalitäten wie bspw. die Java Logging-API auch in der
Datenbank nutzbar.
Ein großer Vorteil der Java stored Procedures in der Oracle-Datenbank ist, dass sie mit einem
PL/SQL-Wrapper versehen werden können. Nach außen hin erscheinen so alle gespeicherten
Prozeduren unabhängig von ihrer tatsächlichen Implementierung als PL/SQL. Wenn Java für
bestimmte Aufgaben besser geeignet ist als PL/SQL (z.B. XML-Parsing), kann diese JavaImplementierung problemlos mit PL/SQL integriert werden.
Sollen in Java implementierte Prozeduren jedoch von außen aufgerufen werden, ist dieses
Verfahren sehr umständlich. Wie in Abb. 1 erkennbar ist, finden gleich zwei Context Switches
statt, wobei die übergebenen Parameter zwischen Java und PL/SQL konvertiert werden müssen.
Die erste Datenkonvertierung findet beim Aufruf des PL/SQL Wrappers durch JDBC statt. Die
Parameter werden von der Java- in die PL/SQL Repräsentation konvertiert. Gleich darauf wird
die eigentliche Java-Implementierung aufgerufen, was zu einer Rückkonvertierung in die JavaRepräsentation führt.
2
JSR steht für Java Specification Request. Eine JSR ist somit eine im Standardisierungsprozeß befindliche Java
Funktionalität. Details zu JSP-114 können unter http://www.jcp.org/en/jsr/detail?id=114 gefunden
werden.
Abb. 1: Zugriff auf gespeicherte Prozeduren in Java außen mit Oracle9i
In Oracle10g kann dieser Umweg vermieden werden. Abb. 2 zeigt, wie das Java native Interface
genutzt wird.
Abb. 2: Zugriff auf gespeicherte Prozeduren in Java von außen mit Oracle10g
Die Verwendung des native Interface erfordert keinen hohen Aufwand. Das jpub-Werkzeug
kann genutzt werden, um die notwendigen Client-Stubs zu erstellen. Der Aufruf ist im folgenden
dargestellt.
jpub –java=oracle.sqlj.checker.JdbcVersion
Das Werkzeug generiert den Quellcode für die Client-Stubs und legt ihn in der Datei
JdbcVersion.java ab. Bei Verwendung dieser Stub-Klasse muss dem Konstruktor ein
Objekt vom Typ eines SQLJ DefaultContext oder einer JDBC Connection übergeben
werden. Alle Methoden der serverseitigen Java-Klasse stehen dann zur Verfügung und können
transparent verwendet werden.
Database Web Services
Die Bedeutung von Web Services nimmt auch im kommerziellen Umfeld immer mehr zu.
Prozeduren und Funktionen, die als Web Service implementiert sind, stehen für Aufrufe mit
SOAP3 über HTTP zur Verfügung. Da die Kommunikation mit Web Services mittels SOAP
standardisiert ist, ist die eigentliche Implementierung des Web Service für den Aufruf nicht
wichtig. Ein in der J2EE Architektur implementierter Web Service kann durchaus aus einer
.NET-Umgebung aufgerufen werden und umgekehrt.
Abb. 3: Aufruf externer Web Services aus der Datenbank.
Jeder Web Service wird durch ein standardisiertes XML-Dokument beschrieben. Dieses
Dokument wird als WSDL-Dokument4 bezeichnet. Ein Beispiel dafür zeigt Abb. 4. Das WSDLDokument enthält zum Aufruf des Web Service nötigen Angaben. Die Clients selbst können in
zwei Varianten implementiert werden.
Der Code für Statische Clients wird vollständig anhand des WSDL-Dokumentes generiert. Da die
Eigenschaften bereits zur Compile-Zeit festgelegt sind, kann der Client schneller entwickelt
werden und ist weniger anfällig für Fehler. Es kann jedoch nur der Web Service, für den der
Client generiert wurde, aufgerufen werden.
Dynamische Clients sind in der Lage, in einem UDDI5 Repository nach Web Services zu suchen,
das WSDL Dokument herunterzuladen um anschließend den Web Service aufzurufen. Der hohen
3
Soap steht für Simple Object Access Protocol3. Stark vereinfacht ausgedrückt ist SOAP RPC mit XMLDokumenten über das HTTP-Protokoll. Die Standardisierung wird vom World Wide Web Consortium (W3C)
vorangetrieben („http://www.w3.org/2000/xp/Group/“)
4
WSDL steht für Web Services Description Language. Die Spezifikation wird vom W3C gepflegt und ist unter
http://www.w3.org/TR/wsdl zu finden.
5
UDDI steht für Universal Discovery and Description Interface. Ein UDDI Repository dient als Verzeichnis für Web
Services. Anhand von Anforderungen kann das UDDI Repository nach Web Services durchsucht werden. Wurde ein
Flexibilität stehen hier mehr Entwicklungsaufwand und höhere Anfälligkeit für Fehler gegenüber.
Dieser Artikel beschränkt sich auf statische Clients. Oracle10g kann Web Services auch
dynamisch aufrufen, der Entwicklungsaufwand ist jedoch – wie bereits beschrieben – höher.
Auch hier sei auf die einschlägige Literatur zum Umgang mit UDDI Repositories und WSDLDokumenten verwiesen.
Abb. 4: WSDL-Dokument eines Web Service (Devisenkurse)
Der Code für den statischen Client kann vollständig mit dem jpub-Werkzeug generiert werden.
Der Aufruf ist im folgenden dargestellt.
jpub
-proxywsdl=http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl
–user=scott/tiger
-package=webservices.currencyexchange
-plsqlpackage=WS_CURRENCY
Web Service gefunden, kann das ihn beschreibende WSDL-Dokument vom UDDI Repository heruntergeladen
werden. Die Spezifikation wird von OASIS gepflegt und kann unter http://www.oasisopen.org/committees/uddi-spec/tcspecs.shtml gefunden werden.
Der Parameter proxywsdl gibt dabei an, wo das WSDLDokument zu finden ist. Eine Position im lokalen Dateisystem kann
ebenso angegeben werden, wie eine URL im Internet. Der Parameter
package legt fest, welchen Namen das Java-Package für den
generierten Java-Code erhalten soll.
Mit diesen Angaben erzeugt das jpub-Werkzeug die rechts
dargestellte Datei- und Verzeichnisstruktur. Darüber hinaus werden
die Java-Klassen automatisch in die Datenbank geladen. Wenn dies
unterdrückt werden soll, sollte die folgende Variante des Aufrufs
verwendet werden.
jpub
-proxywsdl=http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl
–proxyopts=noload
-package=webservices.currencyexchange
-plsqlpackage=WS_CURRENCY
-user=scott/tiger
Bei der Code-Generierung wird der JAX-RPC6 Standard verwendet. Die Klassen unterhalb
Verzeichnis JPubWSDLGenerated liegen nicht als Quellcode vor. Änderungen sind hier auch
nicht erforderlich. Die Datei CurrencyExchangeService.java dient als Einstiegspunkt
von außen. Da sie im Quellcode vorliegt, können hier Anpassungen oder zusätzliche
Einstellungen vorgenommen werden.
Nach außen steht nun die Methode getRate zur Verfügung. Sie kann von anderen Java-Klassen
in der Datenbank transparent verwendet werden. Wenn sie aufgerufen wird, reicht sie den Aufruf
an die generierten Client-Stubs weiter. Die SOAP-Kommunikation über HTTP wird komplett
von diesen Klassen abgewickelt.
Die Java-Laufzeitumgebung ist eng mit dem Sicherheitskonzept der Datenbank verknüpft. Dies
ist auch für den Aufruf eines Web Service relevant, da hier Netzwerkverbindungen geöffnet
werden. Normalerweise hat ein Datenbank-User hierzu nicht das Recht. Der folgende Aufruf
erteilt dem User SCOTT das Recht, durch die Java-Laufzeitumgebung beliebige
Netzwerkverbindungen zu öffnen.
6
JAX-RPC steht für Java API for XML Remote Procedure Calls. Dies ist ein Standard für eine Java API zum
Aufruf von Web Services. JAX-RPC wird Bestandteil von J2EE 1.4 sein. Weitere Informationen sind unter
http://java.sun.com/xml/jaxrpc/index.html zu finden.
begin
dbms_java.grant_permission(
'SCOTT',
'SYS:java.net.SocketPermission',
'*',
'*'
);
end;
Die Datei plsql_grant.sql wurde für diesen Zweck bereits von jpub erzeugt. Es muss als
SYS oder SYSTEM gestartet werden.
Im nächsten Schritt wird der Web Service zusätzlich für SQL und PL/SQL verfügbar gemacht.
Dazu dient das ebenfalls erzeugte Skript plsql_wrapper.sql. Es legt ein PL/SQL Package
mit Namen WS_CURRENCY an. Das Paket enthält die Funktion getRate. Diese Funktion kann
nun in jedem SQL-Kommando verwendet werden.
SELECT
WS_CURRENCY.GETRATE(‘EUR’,’USD’) as EXCHANGE_RATE from dual;
EXCHANGE_RATE
------------.8458
Für die weitere Verwendung sind der Phantasie keine Grenzen gesetzt. Informationen, die von
Web Services geliefert werden, können in die Definition von Views ebenso aufgenommen werden
wie in komplexe ETL-Prozesse eines Data-Warehouse.
XML
Im Bereich XML stand vor allem die Optimierung der Performance im Vordergrund. Die XML
DB wurde in Teilbereichen erweitert. Die folgenden Abschnitte beschreiben die wichtigsten
Neuerungen.
Zeichensatz
Oracle10g erlaubt auch für Zugriffe mit FTP oder WebDAV die Festlegung eines bestimmten
Zeichensatzes. Dies war in Oracle9i nur für Zugriffe mit SQL*Plus möglich (NLS_LANG).
Oracle10g richtet sich für WebDAV oder HTTP-Anfragen nach dem Inhalt des Feldes
AcceptCharset im HTTP-Header.
Für FTP-Zugriffe wurde ein neues Kommando eingeführt. Es kann als sog. Quote-Command wie
folgt gesetzt werden.
ftp> quote set_charset iso-8859-1
Schema Evolution
Mitunter besteht die Notwendigkeit, die Strukturen der in der Datenbank gespeicherten XMLDokumente zu ändern. Da diese Strukturen nach dem W3C-Standard mit einem XML Schema7
beschrieben werden, wird der Vorgang als Schema Evolution bezeichnet. Darunter fällt jede
denkbare Strukturänderung. Das Entfernen von Elementen oder Attributen muss ebenso möglich
sein wie das Hinzufügen.
Wenn die XML-Dokumente dokumentorientiert als CLOB abgelegt werden, verursacht die
Änderung der Strukturen keinen zusätzlichen Aufwand. Die neuen Dokumente werden einfach zu
den alten in die gleiche oder in eine neue Tabelle hinzugefügt.
7
Die
Spezifikation
für
XML
Schema
wird
http://www.w3.org/XML/Schema gefunden werden.
vom
W3C
gepflegt
und
kann
unter
Die objektrelationale Speicherung der XML-Dokumente erfordert bei Strukturänderungen etwas
mehr Aufwand, denn hier werden die XML-Strukturen als Objektmodell in der Datenbank
nachgebildet. Bei einer Änderung gibt es zwei Optionen:
•
Die alte Struktur soll neben der neuen weiterhin existieren.
•
Die neue Struktur soll die alte ersetzen. Dies bedeutet jedoch, dass die bestehenden XMLDokumente zur neuen Struktur migriert werden müssen. Wird bspw. ein Element
hinzugefügt, so müssen auch alle alten Dokumente dieses Element erhalten.
Wenn die alte Struktur weiter existieren soll, empfiehlt es sich, das neue XML Schema zusätzlich
zum alten zu registrieren. Anschließend existieren in der Datenbank zwei Tabellen, eine enthält
die XML-Dokumente mit der alten Struktur, die andere nimmt die mit der neuen Struktur auf.
Wenn die alte Struktur ersetzt werden soll, so müssen die Dokumente entladen, transformiert und
wieder neu geladen werden. In Oracle9i waren dazu folgende manuelle Schritte erforderlich:
1. Alle objektrelational XML-Dokumente werden in eine andere Tabelle ausgelagert. Der
Datentyp dieser Tabelle ist wiederum XMLTYPE, die Speicherungsform sollte jedoch
CLOB-basiert sein.
2. Die ausgelagerten Dokumente werden auf die neue Struktur transformiert. Diese Aufgabe
kann ein XSL-Stylesheet in Verbindung mit der SQL-Funktion XMLTransform()
übernehmen. Dieser Schritt kann auch in einem Schnitt mit der Auslagerung erfolgen.
3. Das registrierte XML Schema wird gelöscht. Alle objektrelational gespeicherten
Dokumente werden damit ebenfalls gelöscht.
4. Das neue XML Schema wird registriert.
5. Die transformierten Dokumente werden in die objektrelationale XML-Tabelle
übernommen.
6. Die Auslagerungstabelle wird gelöscht.
Da diese manuelle Vorgehensweise sehr fehleranfällig ist, wurde sie in Oracle10g automatisiert.
Das Paket DBMS_XMLSCHEMA enthält die Funktion COPYEVOLVE.
PROCEDURE COPYEVOLVE
Argument Name
-----------------------------SCHEMAURLS
NEWSCHEMAS
TRANSFORMS
PRESERVEOLDDOCS
Type
----------------------XDB$STRING_LIST_T
XMLSEQUENCETYPE
XMLSEQUENCETYPE
BOOLEAN
In/Out
-----IN
IN
IN
IN
Default?
--------
DEFAULT
DEFAULT
MAPTABNAME
GENERATETABLES
FORCE
SCHEMAOWNERS
VARCHAR2
BOOLEAN
BOOLEAN
XDB$STRING_LIST_T
IN
IN
IN
IN
DEFAULT
DEFAULT
DEFAULT
DEFAULT
Die wichtigsten Eingabeparameter dieser neuen Prozedur sind einerseits das neue XML Schema
und andererseits das XSL-Stylesheet zur Transformation der bestehenden Dokumente. Die
übrigen Parameter steuern das Verhalten der Prozedur. So legt bspw. der Parameter
MAPTABNAME die Namen der temporären Tabellen zur Aufnahme der XML-Dokumente
während des Transformationsvorgangs explizit fest.
Die oben beschriebenen Schritte werden von der Prozedur automatisch durchgeführt. Damit die
Funktion arbeiten kann, muss genügend Plattenplatz zur Auslagerung der bestehenden
Dokumente vorhanden sein.
Zusammenfassung und Ausblick
Oracle10g führt für Anwendungsentwickler kein neues Paradigma ein. Vielmehr wird bestehende
Funktionalität erweitert und verbessert. Die wichtigsten Änderungen im Java-Umfeld betreffen
die Unterstützung von Industriestandards. Mit der weitgehenden Unterstützung von JDBC 3.0
und Java 1.4 befindet sich Oracle hier auf aktuellem Stand. Die Unterstützung für den Aufruf von
externen Web Services aus der Datenbank trägt der wachsenden Bedeutung dieser Technologie
Rechnung.
Bezüglich der XML DB ist die Unterstützung für Schema Evolution wohl die wichtigste
Neuerung. Vor Anwendung dieser Funktion sollte jedoch in jedem Fall eine genaue Analyse der
Anforderungen stehen. Insbesondere die Frage, ob die bestehenden XML-Dokumente beibehalten
oder migriert werden sollen, spielt eine zentrale Rolle. Auch die Auswirkungen auf bestehende
Anwendungen, deren Abfragen auf der alten Dokumentstruktur beruhen, müssen berücksichtigt
werden.
Kontaktadresse:
Carsten Czarski
Business Unit Database
Oracle Deutschland GmbH
Riesstr. 25
D-80992 München
Telefon:
Fax:
+49(0)89-14302116
+49(0)89-14302977
E-Mail
[email protected]
Internet:
http://www.oracle.com/de
Herunterladen