Eine Einführung in das Java Paket JDBC

Werbung
Eine Einführung in das Java Paket JDBC
Seminararbeit
von
Christian Harwalik
Abteilung Anwendersoftware (AS)
Institut für Parallele und Verteilte Systeme (IPVS)
Universität Stuttgart
Betreuer Uwe Heinkel
Sommersemester 2002
Eine Einführung in das Java Paket JDBC
Seite 2
Zusammenfassung
In dieser Ausarbeitung werden die Hintergründe und der Aufbau von der Java
Database Connectivity beschrieben, und die Funktionsweise erläutert und beurteilt.
Außerdem wird zuvor noch kurz auf die anderen Möglichkeiten eingegangen, um
auf Datenbanksysteme zuzugreifen.
JDBC ist eine offene und standardisierte Schnittstelle für Java-Programme oder
Applets zum Zugriff auf relationale Datenbank-Management-Systeme (RDBMS) fast
aller Hersteller[6]. Es bietet die Möglichkeit, um mit Java auf relationale
Datenbanken zugreifen zu können, SQL Anweisungen auszuführen und die
Ergebnisse zu verarbeiten. JDBC ist sehr mächtig und hat, da es ein Java Paket ist, die
Vorteile, die Java mit sich bringt. JDBC ist ein weit geltender Standard, und eine
Myriade (Vielzahl) der JDBC Treiber stehen heute zum Download zur Verfügung[5].
Eine Einführung in das Java Paket JDBC
Seite 3
Inhaltsverzeichnis
Seite
1. Einführung
1.1 Zugriffe auf Datenbanksysteme
1.2 Was ist JDBC
1.3 ODBC
2. Die Architektur
2.1 Zweischichten Architektur (Direct-to-Database)
2.2 Dreischichten Architektur
3. Die verschiedenen Treiber-Arten
3.1 Typ-1 / JDBC-ODBC-Bridge & ODBC Driver
3.2 Typ-2 / Native API partly Java Driver
3.3 Typ-3 / JDBC Net pure Java Driver
3.4 Typ-4 / Native Protocol pure Java Driver
3.5 Vergleich der Treiber Typen
4. Die Grundstruktur eines JDBC Programms
4.1 Importieren der Klassen
4.2 Laden eines JDBC-Treibers
4.3 Herstellung der Verbindung zur Datenbank
4.4 Anfrage erstellen
4.5 Anfrage ausführen
4.5.1 Statement
4.5.2 PreparedStatement
4.5.3 CallableStatement
4.6 Ergebnisse abfragen
4.7 Metadaten
4.8 JDBC Fehlerbehandlung von SQL Exceptions
4.8.1 java.sql.SqlException
4.8.2 java.sql.SQLWarning
4.8.3 java.sql.DataTruncation
4.9 Mapping von SQL und Java Datentypen
5. Fazit
6. Quellenverzeichnis
4
4
5
5
6
6
7
8
8
9
10
10
11
11
12
12
13
13
13
13
14
15
16
16
16
16
17
17
18
18
19
Eine Einführung in das Java Paket JDBC
Seite 4
1. Einführung
Heutzutage haben Datenbanken und Anwendungen, die auf Datenbanken zugreifen,
große Bedeutung erlangt und diese wird in Zukunft noch zunehmen. Dabei sind
Datenbanken oft die einzige Möglichkeit, den Benutzern eine gemeinsame
Datenbasis zur Verfügung zu stellen. Der Datenbanksystemanwender greift dabei
nicht direkt auf die Daten zu, sondern nutzt spezielle Schnittstellen, über welche die
Daten in zentralen Datenbankmanagementsystemen (DBMS) abgefragt, geändert,
eingefügt oder gelöscht.
Hierbei stellen diese Aktionen auf den Daten in einem Datenbanksystem ein Problem
dar, insbesondere im Hinblick auf die verschiedenen Schnittstellen der unterschiedlichen Anbieter von Datenbanksystemen. Gerade diese unterschiedlichen
Schnittstellen führen zu Problemen auf Seiten der Client-Programme, wenn das
DBMS gewechselt wird oder die Client-Anwendung auf ein DBMS eines anderen
Herstellers zugreift.
Um die Abfragen und Verwaltung von relationalen und objektrelationalen
Datenbanksysteme zu vereinheitlichen, wurde SQL (structured query language)
entwickelt. Allerdings handelt es sich hierbei nicht um eine funktional vollständige
Programmiersprache. Deshalb können Anwendungen nicht direkt in SQL
programmiert werden. Man benötigt also eine Sprache, in welche die SQLStatements „eingebettet“ werden können.
1.1 Zugriffe auf Datenbanksysteme
Da wäre als erstes embedded SQL. Dies ist eine Erweiterung einer „Wirtssprache“
um SQL-Anweisungen. Hier werden SQL-Anweisungen in „Klartext“ in die
Programmiersprachen eingebaut. Um die SQL-Anweisungen zu Kennzeichnen, wird
bei den meisten Wirtssprachen (wie z. B. C/ C++) ein EXEC SQL am Anfang vor die
Anweisung gestellt. Dieser Ansatz erfordert es, die SQL-Quelle durch einen
Precompiler zu schicken, der den Source-Code erzeugt, den der Sprachcompiler
versteht. Die gekennzeichnete Anweisung wird vom Precompiler verarbeitet und der
Rest des Source-Codes wird unberücksichtigt durchgereicht. Die Nachteile hierbei
sind:
-
für jeden Server der verschiedenen Hersteller der Datenbanken muss neu
kompiliert werden;
die prozedurale „Wirtssprache“ muss mit nicht prozeduralem SQL
kombiniert werden.
Eine weitere Möglichkeit ist SQLJ (ehemals JSQL), auch eine Form des embedded
SQL mit der Wirtssprache Java. Die eingebetteten SQL-Anweisungen werden durch
den Präprozessor, den SQLJ-Translator, aufbereitet. Der Präprozessor führt vor dem
eigentlichen Kompilieren des Java-Codes eine Syntax-, Datentyp- und
Schemaüberprüfung durch[10]. Aus den SQLJ-Quelltexten werden Java-Quelltexte
generiert und das Ergebnis, nach dem kompilieren, ist eine Java-Datei, die mit dem
Java-Compiler zu übersetzen ist.
Eine Einführung in das Java Paket JDBC
Seite 5
Eine weitere Möglichkeit ist Java Data Objects (JDO). Es definiert die Semantik, mit
welcher eine Java-Anwendung ihre Datenobjekte in einer Datenbank abfragen und
einfügen kann. JDO hilft dabei, auf Informationen in einem Datenspeicher (wie z. B.
relationale oder objekt-orientierte Datenbanken) zuzugreifen, wobei diese
Informationen als Java-Objekte erscheinen, so dass die Daten durch die direkte
Nutzung von Java manipuliert werden können.
1.2 Was ist JDBC
Durch Java Database Connectivity (JDBC), der Firma Sun Microsystems, gibt es noch
eine weitere Möglichkeit, außer JDO, SQLJ usw., um auf Datenbanksysteme
zuzugreifen. JDBC stellt eine Schnittstelle zur Verfügung, mit deren Unterstützung
SQL-Datenbankanfragen gestellt und ausgewertet werden können. Im allgemeinen
erfüllt JDBC drei Aufgaben: Es eröffnet eine Verbindung zu einer Datenbank, stellt
eine SQL-Anfrage und bearbeitet die Ergebnisse. Bei JDBC ist das
Datenbankverwaltungssystem unerheblich, im Bezug auf den Hersteller
beziehungsweise den Anbieter dieses Datenbankverwaltungssystems. Dies bedeutet
für JDBC, dass es Treiber für eine Vielzahl von Datenbanksystemen zur Verfügung
stellt, gerade im Bezug auf die verschiedenen Datenbankverwaltungssysteme. Für
die wenigen, für die es keinen JDBC spezifischen Treiber gibt, wird die ODBCSchnittstelle in JDBC angeboten. Einen ODBC Treiber stellt eigentlich jeder
Hersteller von Datenbankmanagementsystemen zur Verfügung. Somit kann JDBC,
über diese ODBC-Schnittstelle, auch für Datenbanken verwendet werden, für welche
es nicht direkt in JDBC einen Treiber gibt. Die Anweisung kommuniziert mit der
JDBC-Schnittstelle, und diese dann mit dem Datenbanksystem (z.B.: Oracle, DB2,
Sybase, usw.). Es bietet die Möglichkeit, für den Entwickler von Anwendungen, eine
Datenbankanwendung hauptsächlich in Java zu schreiben, d.h. man benötigt nur
eine Programmiersprache und geringe Kenntnisse über SQL, oder man hat eine
genaue Spezifikation der SQL-Statements, die ausgeführt werden. Da diese
Schnittstelle komplett in Java implementiert ist, kann sie einfach in JavaApplikationen eingebunden werden und hat damit auch alle sonstigen Vorteile
Javas, wie zum Beispiel die Plattformunabhängigkeit, zumindest wenn man nicht auf
eine nativen Treiber (wird später noch behandelt) zurückgreifen muss, oder
Verwendung in Verbindung mit Netzwerken, wie dem World Wide Web.
Die Vorteile lassen sich kurz zusammenfassen.
-
Client/Server-Architektur, eingebaute Netzwerkfähigkeit
nutzbar für fast jedes relationale DBMS
voller Zugriff auf die Metadaten einer DB (was später noch erläutert wird)
der Datenbankzugriff wird über eine URL identifiziert und ist damit eindeutig
und leicht verständlich (was später noch erläutert wird).
Eine Einführung in das Java Paket JDBC
Seite 6
1.3 ODBC
Open Database Connectivity (ODBC) ist eine Schnittstelle, welche von Microsoft
entwickelt wurde[7]. Diese Schnittstelle stellt ebenfalls einige der oben erwähnten
Möglichkeiten, auf Datenbanken zugreifen zu können, zur Verfügung. Die
Unterstützung von ODBC ist nicht auf Microsoft beschränkt. DBMS-Hersteller wie
Oracle, Informix, Novell, IBM, usw. unterstützen ODBC. SQL-Befehle werden bei
ODBC zur Kommunikation mit dem Datenbanksystem eingesetzt. Diese werden in
ODBC-Anweisungen eingepackt. Es findet keine Syntaxkontrolle statt, da ODBC die
SQL-Befehle nicht interpretiert. Die SQL-Befehle werden an einen Treiber geschickt,
welcher vom Hersteller der Datenbank zur Verfügung gestellt wird. Der Treiber
sendet die Befehle an die Datenbank, nimmt die Antworten entgegen und übergibt
sie an das ODBC-Programm.
2. Die Architektur
Es existieren zwei unterschiedliche Architekturen um mittels JDBC eine Verbindung
zwischen einer Applikation und einer Datenbank aufzubauen. Welche eingesetzt
wird, ist von den Anforderungen der Anwendung bzw. der Hardware- und
Software-Umgebung des Einsatzgebietes von JDBC abhängig. Außerdem ist die Art
des zur Verfügung stehenden Treibers bei der Entscheidung maßgeblich, was später
noch behandelt wird.
2.1 Zweischichten Architektur (Direct-to-Database)
In der „Two-Tier-Architecture“ (Abb. 1) wird durch eine Applikation eine
Verbindung zur Datenbank durch einen Datenbanktreiber aufgebaut. Dieser Treiber
ist dann für den Datenaustausch mit der Datenbank verantwortlich ist. Die
Applikation ist somit zuständig für die Funktionalität des Datenaustausches.
Abb. 1 Two-Tier Architektur [13]
Diese Architektur entspricht der klassischen Client-Server-Architektur. Ein typisches
Beispiel ist das Laden eines Java-Applets mit Hilfe eines Browsers auf dem Client,
Eine Einführung in das Java Paket JDBC
Seite 7
welches vom Server geladen wird. Dieses Applet kommuniziert direkt mit dem
Datenbankserver und kann, aufgrund der strengen Sicherheitsvorschriften für
Applets, nur mit dem Rechner in Verbindung treten, von welchem das Applet
geladen wurde. Dies bedeutet, dass Web-Server und die Datenbank auf dem selben
Rechner zur Verfügung stehen müssen. Es existieren zwei Arten des Zweischichten
Modells:
1. Ein Java-Applet, auf einem Client System, wird von einem Server geladen
und verbindet sich über ein DBMS-spezifisches Protokoll mit der
Datenbank.
2. Ein Java-Applet wird vom Server auf das Client System geladen und
verbindet sich über einen nativen DBMS-Treiber mit der Datenbank,
welche ebenfalls auf dem gleichen Rechner liegen muss wie der WebServer mit dem sich das Applet verbindet.
Auf diese beiden Modelle wird bei den Treibertypen genauer eingegangen.
Zu diesem Zweischichten-Modell gibt es noch einige weitere Dinge anzumerken.
Erstens wird eine leistungsfähige Maschine vorausgesetzt um einen Web-Server und
einen Datenbankserver auf ein und demselben Rechner laufen zu lassen. Außerdem
ist die Sicherheit der Datenbank geringer als bei dem Dreischichten Modell, da der
Client direkt an den Rechner kommt, auf dem der Datenbankserver ist. Des weiteren
muss der „pure java-„-Treiber bei jeder Verbindung zu dieser Datenbank erneut vom
Web-Server geladen werden, was die Ladezeit des Applets verlängert, vereinfacht
dafür aber die Softwareverteilung und Portabilität. Im Gegensatz dazu ist das Laden
des nativen Treibers vom lokalen Rechner bedeutend schneller, aber es setzt ein
Applet voraus und erschwert die Softwareverteilung und schränkt die Portabilität
ein. Wenn eine Datenquelle nun verteilt vorliegt, also erstens der Web-Server und
der DB-Server auf verschiedenen Maschinen liegen oder die Daten auf verschiedenen
DB-Servern liegen, so muss entweder der JDBC–Treiber über Netzwerkfähigkeiten
verfügen oder man benutzt das Dreischichten Modell.
2.2 Dreischichten Architektur
Bei der sogenannten „Three-Tier-Architecture“, Abb. 2, liegen der Web-Server und
der Datenbankserver auf getrennten Rechnern, bzw. können die Daten auch auf
verschiedenen Datenbankservern zur Verfügung stehen. Dieses Modell benötigt
einen „middle-tier Server“, welcher als Gateway zu den Datenbankservern dient.
Am Beispiel eines Applets, wird bei dieser Architektur ein Applet vom Web-Server
geladen, welches sich über ein Protokoll, welches von dem Datenbanksystem
unabhängig ist, mit einem Gateway auf dem Web-Server verbindet und dann als
Datenbank-Client die Abfragen für das Applet übernimmt. Die Ergebnisse der
Datenbank werden anschließend an das Applet zurückgesendet. Ein Beispiel für
dieses Modell ist eine Verbindung zweier Java-Applets mit Hilfe von Remote
Method Invocation. RMI ermöglicht Java mit verteilten Systemen zu kommunizieren.
Eine Einführung in das Java Paket JDBC
Seite 8
Es stellt Java-Klassen und entsprechende Methoden bereit, um vom Client-Applet
aus mit Serverobjekten Daten auszutauschen.
Abb. 2 Three-Tier Architektur [13]
Hierzu sollte man anmerken, dass die Trennung von Web-Server und
Datenbankserver die Maschinen auf denen diese Server laufen entlasten. Weiterhin
erhöht es die Sicherheit bei Zugriffen auf DB-Server, da der Zugriff nur über ein
Gateway möglich ist, auf dem zum Beispiel Java Applikationen und JDBC Treiber
sind um mit der/den Datenbank/en zu kommunizieren (wie in Abbildung 2
ersichtlich ist). Allerdings ist dafür die Programmierung des Gateways erheblich
komplexer, da eine Umsetzung der unabhängigen Datenbanksystem-anweisungen in
spezifische Datenbanksystembefehle benötigt wird.
3. Die verschiedenen Treiber-Arten
Die Anwendung von JDBC verlangt den Einsatz von Treibern für die verwendete
Datenbank, welche über den sogenannten JDBC-Treiber-Manager verwaltet bzw.
geladen werden. Diese Treiber lassen sich in vier verschiedene Kategorien
unterteilen. Die Unterschiede in den Architekturen der einzelnen Treiber werden
nachfolgend erläutert.
Eine Einführung in das Java Paket JDBC
Seite 9
3.1 Typ-1 / JDBC-ODBC-Bridge & ODBC Driver:
Bei dieser Variante wird der Typ 1 Treiber (JDBC-ODBC-Bridge) benützt, um über
eine ODBC-Schnittstelle mit der Datenbank zu kommunizieren. Ein solcher Treiber
wird in JDBC angeboten. Allerdings muss auf allen Clients eine ODBC-Schnittstelle
installiert sein (Abb. 3).
Die grau-schattierten Boxen sind der Java bzw. der JDBC Teil dieser Architektur.
Abb. 3 JDBC-ODBC-Bridge und ODBC Driver [1]
3.2 Typ-2 / Native API partly Java Driver:
Bei dieser Architektur wird der native ODBC-Treiber durch einen nativen
herstellerabhängigen Treiber (z.B. einen Oracle-Treiber) ersetzt. Er ist zur
Anwendung hin in Java und zur Datenbank hin nativ programmiert. Dieser Treiber
ist plattformabhängig und muss, zur Anwendung hin, bei jedem Client installiert
werden (Abb. 4).
Auch hier sind die grau-schattierten Boxen der Teil, welcher durch JDBC/Java zur
Verfügung gestellt wird.
Eine Einführung in das Java Paket JDBC
Seite 10
Abb. 4 Native API partly Java Driver [1]
3.3 Typ-3 / JDBC Net pure Java Driver :
Abb. 5 JDBC Net pure Java Driver [1]
Bei diesem Treiber-Typ (Abb. 5) erspart man dem Client die lokale Installation eines
Treibers durch den Einsatz einer serverseitigen Middleware-Installation, welche den
Eine Einführung in das Java Paket JDBC
Seite 11
Datenbankzugriff realisiert. Die Middleware beziehungsweise das Gateway dient als
Verteilungsplattform. Sie macht die Kommunikation zwischen allen möglichen JavaClients und den unterschiedlichsten Datenbankmanagementsystemen möglich.
Der universelle Treiber kann vom Server, durch JDBC (hier grau-schattiert) geladen
werden.
3.4 Typ-4 / Native Protocol pure Java Driver:
Bei dieser Variante werden Treiber verwendet, welche in purem Java-Code
programmiert sind, um eine Anbindung von nativem Code zu vermeiden. Diese
Alternative bietet, durch die fehlende Einbindung von nativem Code, auf der einen
Seite die Unterstützung der Plattformunabhängigkeit von Java und andererseits dem
Client die Möglichkeit den Treiber vom Webserver zu laden (Abb. 6).
Abb. 6 Native Protocol pure Java Driver [1]
3.5 Vergleich der Treiber Typen
Zu beachten ist, dass die Typen 1 und 3 keine Netzwerkfähigkeiten zur Verfügung
stellen um direkt auf ein DBMS zuzugreifen. Sie können also nur mit Hilfe JDBC
fremder Komponenten, wie ODBC Treiber, in Applets verwendet werden. Im
Gegensatz dazu verwenden die Typen 2 und 4 ein Netzwerkprotokoll, wodurch
entfernte Datenbanken angesprochen werden können. Leider sind diese
Treibertypen nicht für alle Datenbanken verfügbar, so dass dann auf den Typ 1 oder
3 zurückgegriffen wird. Die Typen 3 und 4 bieten allerdings alle Vorteile von Java,
da sie komplett in Java geschrieben sind.
4. Die Grundstruktur eines JDBC Programms
Jede JDBC Anwendung kann zuerst einmal grob in drei Bereiche unterteilt werden.
Zuerst wird eine Verbindung zur Datenbank hergestellt. Danach werden SQL
Eine Einführung in das Java Paket JDBC
Seite 12
Anfragen formuliert. Darauf können dann die Ergebnisse bearbeitet werden, wie in
Abbildung 7 ersichtlich ist.
Abb. 7 Elemente einer JDBC Anwendung
Wenn man sich die Schritte genauer ansieht lässt sich eine feinere Einteilung
vornehmen:
-
Importieren der notwendigen Java-Klassen und Interfaces
Laden eines JDBC-Treibers
Herstellung einer Verbindung zur Datenbank
Erstellen der Statements
Ausführen der Statements
Abfragen der Ergebnisse
Beenden der Verbindung zur Datenbank
Diese Schritte liefern jeweils ein Objekt aus einer JDBC-Klasse/Schnittstelle, die
Methoden für den folgenden Schritt bereitstellen (java.sql.DriverManager,
java.sql.Connection, java.sql.Statement, java.sql.ResultSet). Die einzelnen Schritte
werden im Folgenden weiter ausgeführt.
4.1 Importieren der Klassen
Das Paket java.sql stellt alle notwendigen Klassen und Interfaces zur Ausführung
von JDBC zur Verfügung. Die Klassen müssen am Beginn des Java-Programms
importiert werden. Für JDBC wäre dies:
import java.sql.*;
Der * sorgt dafür, dass alle Klassen in diesem Paket importiert werde.
4.2 Laden eines JDBC-Treibers
Zur Ausführung der JDBC-Anweisungen muss ein Datenbanktreiber geladen
werden, der diese Anweisungen in eine Sprache (Code) umwandelt, die von dem
jeweiligen Datenbanksystem verstanden wird. Zum Beispiel die JDBC-ODBC-Bridge,
die in Verbindung mit einem lokal installierten und eingerichteten ODBC-Treiber
jede Datenbank, die einen ODBC-Treiber zur Verfügung stellt, ansprechen kann,
oder ein nativer Treiber für eine spezielle Datenbank (z. B. der Oracle-JDBC-Treiber).
Im Normalfall übernimmt der DriverManager, auf den später noch eingegangen
wird, die Auswahl des Treibers.
Eine Einführung in das Java Paket JDBC
Seite 13
4.3 JDBC URLs
Durch den Aufruf der Methode DriverManager.getConnection erhält man ein
Objekt der Klasse Connection. Dies repräsentiert eine Verbindung. Diese Methode
erwartet als Argument eine URL der Struktur jdbc:<Unterprotokoll>:<Untername>.
Ein Beispiel hierfür ist (User und Passwort sind optional):
Connectin con = DriverManager.getConnection(“jdbc:odbc:Test”, User, Pw);
4.4 Herstellung der Verbindung zur Datenbank
Sobald die DriverManager Klasse geladen und registriert ist, besteht die Möglichkeit
eine Verbindung zur Datenbank herzustellen. Wenn nun eine Verbindung mit Hilfe
der Methode Drivermanager.getConnection gestartet wird, prüft der
DriverManager jeden Treiber der Reihe nach, und verwendet den ersten passenden.
Hierbei kann es auch vorkommen, dass es mehrere passende Treiber gibt. Die
Reihenfolge, welcher Treiber nach einem anderen kommt, wird in der Reihenfolge
festgelegt, in der die Treiber registriert wurden (die Treiber in jdbc.drivers werden
immer zuerst registriert). Hier ein Beispielcode für eine Verbindung mit einem JDBCODBC-Bridge-Treiber:
Class.forName("jdbc.odbc.JdbcOdbcDriver"); //loads the driver
String url = "jdbc:odbc:fred";
Connection con = DriverManager.getConnection(
url, "userID", "passwd");
Die Variable „con“ stellt einen Anschluss zur Datenquelle „fred“ dar, welche verwendet werden kann um SQL Anweisungen zu erstellen und auszuführen.
4.5 Anfragen erstellen
Es bestehen drei Möglichkeiten um eine SQL-Anweisung an die verbundene
Datenbank zu senden. Eine Anfrage kann mit den Interface Statement ( für einfache
Anfragen), PreparedStatement (für IN-Parameter, wird precompiliert und für spätere
Verwendung gespeichert) oder CallableStatement (um Stored Procedures
auszuführen, zusätzlich OUT- und INOUT-Parameter) gestellt werden. Wenn eine
Verbindung zu einer Datenbank besteht, so können die Methoden createStatement,
prepareStatement oder prepareCall aus dem Objekt Connection aufgerufen werden.
4.5.1 Statement
Eine Anweisung kann nur formuliert werden, wenn eine Instanz des Interface
Statements erzeugt wurde. Ein Beispiel um eine Instanz einer Verbindung (con) auf
die Instanz eines Statements (stmt) zu erzeugen wäre:
Connection con = DriverManager.getConnection(url, "sunny", "");
Statement stmt = con.createStatement();
Eine Einführung in das Java Paket JDBC
Seite 14
Die Anfragen können durch die Methoden executeQuery, executeUpdate oder
execute gestellt werden. Die Methode executeQuery liefert als Resultat eine Liste
wie zum Beispiel der SQL-Aufruf „SELECT“.
ResultSet rs = stmt.executeQuery("SELECT Name,
Berufsbezeichnung, Gehalt FROM Mitarbeiter");
Diese Anweisung liefert in der Variablen „rs“ eine scrollbare Liste mit den
Ergebnissen des SQL Statements zurück.
Die Methode executeUpdate wird benötigt um Veränderungen an Tabellen
durchzuführen. Mit dieser Methode können die SQL-Anfragen INSERT, UPDATE,
DELETE, CREATE TABLE, DROP TABLE und ALTER TABLE formuliert werden.
Die Rückgabewerte bei den Methoden INSERT, UPDATE und DELETE sind Zahlen,
der veränderten, eingefügten oder gelöschten Zeilen. Bei CREATE TABLE, DROP
TABLE und ALTER TABLE ist der Rückgabewert immer 0.
stmt.executeUpdate ("DROP TABLE TB1");
Die Methode execute wird verwendet wenn mehrere ResultSets zurückgeliefert
werden. Dabei können diese Listen oder Updatewerte enthalten. Diese Methode
kann dann verwendet werden, wenn es möglich ist, dass eine Anweisung mehr als
nur ein Resultat zurückgibt, mehr als nur einen Rückgabewert (Zahlenwert) liefert
oder eine Kombination von Resultat und Rückgabewert darstellt. Dies kann zum
Beispiel zustande kommen, wenn man in der Datenbank gespeicherte Prozeduren
ausführt. Im Normalfall kennt man allerdings die
Rückgabewerte einer
gespeicherten Prozedur, wenn man sie aufruft.
4.5.2 PreparedStatement
Dieses Interface erbt vom Interface Statement. Es unterscheidet sich vom Statement
auf zwei Arten. Erstens enthalten die Instanzen von PreparedStatement SQLAnweisungen, die bereits kompiliert worden sind. Ein Beispiel für ein
PreparedStatements ist: Wenn eine Anfrage die Daten über eine Person liefern soll,
diese anhand ihres Namens ermittelt wird und wenn diese Anfrage nun für
verschiedene Personen (Müller, Maier, Schmitt, usw.) wiederholt werden soll wird
hierfür ein PreparedStatement benutzt. Zweitens kann eine SQL-Anweisung im
PreparedStatement ein oder mehrere IN-Parameter enthalten. Ein IN-Parameter ist
eine Art Variable, deren Inhalt beim Erstellen der Anweisung noch nicht spezifiziert
war. Diese Möglichkeit, IN-Parameter in ein Statement einzugeben, ist der Grund
warum dieses Statement „prepared“ heißt. Ein „?“ dient als alias bzw. Platzhalter für
die IN-Parameter, und diesem können zur Laufzeit verschiedene Werte zugewiesen
werden.
PreparedStatement pstmt = con.prepareStatement(
"UPDATE Mitarbeiter SET Gehalt = ? WHERE Name = ?");
Dies ist die Vorbereitung einer Anfrage, bei der die Werte für die Variablen „Gehalt“
und „Name“ während der Laufzeit des Programms (z.B. einer Java Applikation)
Eine Einführung in das Java Paket JDBC
Seite 15
gesetzt werden können. Die Werte werden mit den Methoden setByte, setShort,
setString, setLong, usw. gesetzt. Dies macht es möglich eine SQL-Anfrage mit
verschiedenen Parametern zu stellen, ohne jedes Mal eine Instanz des Interfaces
Statement zu erstellen.
PreparedStatement.setLong(1, 4550);
PreparedStatement.setString(2, Maier);
Das erste Argument des „con.prepareStatement“ hat die Ordinalposition 1. Es
dient der Zuordnung des ersten Parameters sowie des zugehörigen Wertes. In
diesem Fall bewirkt die setLong Methode, dass die Variable „Gehalt“ auf „4550“ und
„Name“ auf „Maier“ gesetzt wird.
Diese Statements beziehungsweise Anfragen werden dann mit der entsprechenden
executeQuery, executeUpdate und execute Methode gestellt.
PreparedStatement.executeUpdate();
Nun müssen nur noch die Parameter gesetzt werden, bevor man die Anfrage senden
kann. Dazu dienen die Methoden setxxx. Dabei sollte man aber auf die
entsprechende Konvertierung achten.
4.5.3 CallableStatement
Diese Methode bietet die Möglichkeit „stored procedures“, in der Datenbank
gespeicherte Prozeduren, auszuführen. Ein CallableStatement-Objekt enthält den
Aufruf einer gespeicherten Prozedur. Ein Beispiel hierfür wäre:
procedure1 = Connection.prepareCall("{call getTestData(?, ?)}");
Als Erweiterung zu PreparedStatement können die Parameter nicht nur
Eingabewerte sondern auch Ausgabewerte darstellen. Die Ergebnisse werden dann
mit Methoden der Form getxxx ermittelt. Auf die Behandlung der Ergebnisse wird
später noch genauer eingegangen. Dazu müssen die Fragezeichen, welche die
Ausgabewerte enthalten werden, entsprechend initialisiert werden. Dabei wird der
Typ des Rückgabewertes angegeben.
CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter(2, java.sql.Types.BIT);
ResultSet rs = cstmt.executeQuery();
// . . . retrieve result set values with rs.getXXX methods
byte x = cstmt.getByte(1);
java.math.BigDecimal n = cstmt.getBigDecimal(2);
Noch ein Hinweis zur Zuordnung der Platzhalter (Fragezeichen) und dem
zugewiesenen Inhalt, in obigem Beispiel verweist die 1 in der Methode
registerOutParameter auf das vordere Fragezeichen und die 2 in der Zeile
darunter auf das hintere Fragezeichen.
Eine Einführung in das Java Paket JDBC
Seite 16
4.6 Ergebnisse Abfragen
Der Rückgabewert bzw. das ResultSet, ist ein Objekt, welches die Ergebnisse einer
SQL-Anfrage enthält. Diese Daten können über die Methoden next, deleteRow,
findColumn, getArray, getString, usw. bearbeitet und spezielle Ergebnisse
selektiert werden. Je nach Ergebnistyp (Sting, Array, Integer usw.) muss die
entsprechende Methode aufgerufen werden. Die Methode ResultSet.next macht die
erste bzw. die nächste Reihe im ResultSet verfügbar und gibt false zurück, wenn
keine Daten mehr zur Verfügung stehen. Die allgemeine Form eines ResultSet
entspricht einer Tabelle mit Spaltenbezeichnung und den zugehörigen Werten.
4.7 Metadaten
Das Interface DatabaseMetaData liefert Informationen zu den Fähigkeiten/
Metadaten des Datenbanksystems und des JDBC-Treibers. Dies ist von großem
Vorteil für die Entwicklung von Datenbankwerkzeugen und auch allgemein für die
Entwicklungsumgebung. Das Interface wird erzeugt mit:
DatabaseMetaData Metadaten = con.getMetaData();
Die Methode getMetaData wird auf die Instanz der Verbindung angewandt und
über dieses DatabaseMetaData-Objekt lassen sich Informationen über die Datenbank
abfragen(z. B. Produktname der Datenbank und dazugehörende Version, JDBCTreibername, die maximale Anzahl gleichzeitig geöffneter Statements, usw.).
Das Interface ResultSetMetaData stellt Informationen über die Datentypen und
Eigenschaften der Spalten in einem ResultSet zur Verfügung. Ein Beispiel zum
erzeugen eines ResultSetMetaData-Objekt ist:
ResultSet rs = stmt.executeQuery(“SELECT Name, Alter, Gehalt FROM
Mitarbeiter”);
ResultSetMetaData rsmd = rs.getMetaData();
ResultSetMetaData ist bei der Methode execute besonders nützlich, da hier die
Anzahl und Art der Ergebnisse zur Übersetzungszeit unbekannt sind.
4.8 JDBC Fehlerbehandlung von SQL Exceptions
Jede Methode der JDBC Klassen und Interfaces, bis auf die 5 Hilfsklassen (Date,
DriverPropertyInfo, Time, Timestamp, Types) kann eine SQL Exception verursachen
und ausgeben. Das macht die Fehlerbehandlung zu einem wichtigen Teil jeder
Anwendung.
4.8.1 java.sql.SQLException (erweitert java.lang.Exception)
Dies ist die Basisklasse aller anderen JDBC-Exceptions. Sie wird von Datenbankzugriffsfehlern oder anderen Fehlern ausgelöst. Um mehrere Fehler behandeln zu
Eine Einführung in das Java Paket JDBC
Seite 17
können werden in ihr die Fehler verkettet. Die wichtigsten Methoden dieser Klasse
sind:
-
String getMessage (): Diese Methode liefert die Fehlerbeschreibung der
Exception
int getErrorCode(): Hier erhält man den „exception code“ für die ausgelöste
SQLException
String getSQLState(): Dies gibt eine Fehlermeldung nach der XOPEN SQLstate
Konvention an
SQLException getNextException(): Hier wird die nächste verkettete
Fehlermeldung oder null zurückgegeben
Es ist bei SQLExceptions nicht zwangsläufig notwendig, dass beim Auslösen einer
solchen Exception die verursachende Methode nicht ausgeführt wird. Also ist es am
sichersten nach einer Exception die Methode rollback zu nutzen um von vorne zu
beginnen.
4.8.2 java.sql.SQLWarning (erweitert java.sql.SQLException)
Diese Klasse stellt Informationen über Warnungen beim Zugriff auf eine Datenbank
zur Verfügung. Nach dem Aufruf der Methode getWarnings wird die erste
Warnung bereitgestellt. Existieren mehrere Warnungen, kann man mit der Methode
getNextWarning die nächste Warnung abrufen. Bei den SQLWarnings ist zu
beachten, dass bei Ausführung einer neuen Anweisung die Warnung einer
vorangegangenen Anweisung entfernt wird. Die Informationen(z. B. ErrorCode), die
beim Auftreten einer Warnung zur Verfügung gestellt werden, sind dieselben wie
bei den SQLExceptions. Die wichtigsten Methoden sind hier:
-
SQLWarning getNextWarning(): Diese Methode gibt die nächste verkettete
Warnmeldung zurück
ansonsten existieren hier die gleichen Methoden wie bei SQLExceptions
4.8.3 java.sql.DataTruncation (erweitert java.sql.SQLWarning)
Diese Klasse erbt von SQLWarning. Sie stellt Informationen zur Verfügung wenn
von JDBC unerwartet Datenwerte abgeschnitten werden. Es kann unter bestimmten
Umständen passieren, dass nur ein Teil eines Datenfeldes in eine Datenbank
geschrieben oder aus ihr gelesen wird. Geschieht das „Kürzen“ (engl. truncation)
beim Lesen aus einer Datenbank wird eine SQLWarning ausgegeben, beim Schreiben
wird allerdings eine SQLException ausgelöst. Hier sollte beachtet werden, dass mehr
Daten gesendet werden als der Treiber oder die Datenbank aufnehmen können,
wenn während des Schreibens Daten gekürzt werden. In diesem Fall sollte ein
DataTruncation-Objekt als eine SQLException ausgelöst werden.
4.9 Mapping von SQL und Java Datentypen
Beim arbeiten mit Datenbanken ist das Mapping oder auch Abbilden der Datentypen
ein sehr wichtiger Punkt. Der Grund ist, es gibt bei SQL andere Datentypen als bei
Eine Einführung in das Java Paket JDBC
Seite 18
Java. Daher muss dafür gesorgt werden, dass die Daten korrekt abgebildet werden.
Allerdings bedeutet dies nicht, dass die Abbildung von Java und SQL Datentypen
isomorph sein muss. Zum Beispiel der Java Datentyp String, der nicht vollständig
auf SQL Datentyp CHAR abgebildet werden kann. Um diese unterschiedlichen
Datentypen aufeinander abbilden zu können, definiert JDBC eine Menge generischer
SQL-Typen in der Klasse java.sql.Types. Die Umsetzung erledigt im allgemeinen der
Treiber.
Abbildung von SQL auf Java Datentypen und von Java auf SQL Datentypen
Abb. 8 Mapping Tabelle
5. Fazit
Das Paket JDBC eignet sich als Schnittstelle zwischen Java und relationalen
Datenbanken beziehungsweise Datenbankmanagementsysteme sehr gut. Dank des
Treiber-Konzepts kann sich der Anwendungsentwickler auf die Entwicklung seiner
Anwendung konzentrieren und muss kaum Zeit für die Anbindung verschiedener
DBMS aufwenden. Mit Hilfe von JDBC lassen sich sehr komplexe und aufwendige
Aufgaben und Probleme umsetzen beziehungsweise lösen .
Eine Einführung in das Java Paket JDBC
Seite 19
6. Quellenverzeichnis
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
[15]
J. Melton, A. Eisenberg: Understanding SQL and Java Together. Morgan
Kaufmann, 2000.
A.Kemper, A.Eickler: Datenbanksysteme – Eine Einführung; 4.Auflage;
Oldenbourg Verlag München Wien; 2001
Getting Started with the JDBC API von Sun Microsystems Inc.
http://java.sun.com/j2se/1.4/docs/guide/jdbc/getstart/GettingStartedTOC.fm.ht
ml
Sybase jConnect for JDBC Technical Whitepaper von Sybase
http://www.sybase.com/detail/1,6904,1009766,00.html#top
Developer’s Guide to Building XML-based Web Services with J2EE[tm] von
James Kao Juni 2001 http://www.theserverside.com/resources/pdf/J2EEWebServices-DevGuide.pdf
Enterprise Application Integration – Standardisierte Integration zur
Bewältigung der IT-Herausforderungen von morgen von KPNG Consulting AG
http://www.kpmg.de/services/consulting/ebusiness/docs/KPMG_EAI_Whitepap
er_deutsch2002.pdf
Whitepaper zum Einsatz der HOB-Produkte HOBLink DRDA, HOBDB online
und HOB Database Gateway Extension von HOB
http://www.hob.de/produkte/connect/drda_wpd.htm
Gunter Saake und Kai-Uwe Sattler: Datenbanken & Java: JDBC, SQLJ und
ODMG; 1. Auflage; Heidelberg: dpunkt-Verlag; 2000
Hans Dicken: JDBC; 1.Auflage; Bonn: Internat. Thomson Publ.; 1997
Java Seminar: SQLJ – Embedded SQL in Java von Martin Fuchs
http://www.fsai.fh-trier.de/fsai/seminare/archiv/0006/SQLJ.pdf
Using Java DataBase Connectivity von Sun Microsystems Inc.
http://docs.sun.com/source/816-4685/index.html
JDBC TM Data Access API Relationship of JDO and Java TM 2 Platform,
Enterprise Edition APIs von Sun Microsystems Inc.
http://java.sun.com/products/jdbc/related.html
JDBC™ 3.0 Specification von Sun Microsystems Inc.
http://java.sun.com/products/jdbc/
Einführung in JDBC – Tutorium zur Internet-Datenbank-Einbindung in Java
über JDBC und RMI
Datenbanken: Eine Einführung http://www.in.tuclausthal.de/~hoerner/hs_datenbanken/DBEinfuehrung.pdf
Herunterladen