Date: Fri, 10 Nov 2023 15:11:48 +0100
Subject: add new repo
---
.../hjp5/html/k100267.html | 633 +++++++++++++++++++++
1 file changed, 633 insertions(+)
create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100267.html
(limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100267.html')
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100267.html b/Master/Reference Architectures and Patterns/hjp5/html/k100267.html
new file mode 100644
index 0000000..ebab778
--- /dev/null
+++ b/Master/Reference Architectures and Patterns/hjp5/html/k100267.html
@@ -0,0 +1,633 @@
+
+
+
+Handbuch der Java-Programmierung, 5. Auflage
+
+
+
+
+
+
+
+
+
+
+
+
+42.2 Grundlagen von JDBC
+
+
+
+
+
+
+
+42.2.1 Öffnen einer Verbindung
+
+
+Bevor mit JDBC auf eine Datenbank zugegriffen werden kann, muss zunächst
+eine Verbindung zu ihr hergestellt werden. Dazu muss der Datenbanktreiber
+geladen und initialisiert und mit Hilfe des Treibermanagers ein Verbindungsobjekt
+beschafft werden. Es bleibt während der gesamten Verbindung bestehen
+und dient als Lieferant für spezielle Objekte zur Abfrage und
+Veränderung der Datenbank. Alle Klassen zum Zugriff auf die JDBC-Schnittstelle
+liegen im Paket java.sql,
+das am Anfang des Programms importiert werden sollte:
+
+
+
+
+
+
+import java.sql.*;
+
+
+ |
+
+
+
+
+Jeder JDBC-Treiber hat einen statischen Initialisierer, der beim Laden
+der Klasse aufgerufen wird. Seine Aufgabe besteht darin, sich beim
+Treibermanager zu registrieren, um
+bei späteren Verbindungsanfragen von diesem angesprochen werden
+zu können. Das Laden der Treiberklasse wird üblicherweise
+durch Aufruf der Methode forName
+der Klasse Class
+erledigt (siehe Abschnitt 43.2.2).
+Um einen Treiber zu laden, muss man also seinen vollständigen
+Klassennamen kennen:
+
+
+Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
+
+
+
+
+sun.jdbc.odbc.JdbcOdbcDriver
+ist der Name der JDBC-ODBC-Bridge, mit der die oben erwähnten
+Typ-1-Treiber realisiert werden. Die Namen alternativer Treiber sind
+der Dokumentation des jeweiligen Herstellers zu entnehmen.
+
+
+Nachdem der Treiber geladen wurde, kann er dazu verwendet werden,
+eine Verbindung zu einer Datenbank aufzubauen. Dazu wird an die statische
+Methode getConnection
+der Klasse DriverManager
+ein String und eventuell weitere Parameter übergeben, um den
+Treibertyp, die Datenbank und nötigenfalls weitere Informationen
+festzulegen. getConnection
+gibt es in drei Ausprägungen:
+
+
+
+
+
+
+static Connection getConnection(
+ String url
+)
+
+static Connection getConnection(
+ String url,
+ String user,
+ String password
+)
+
+static Connection getConnection(
+ String url,
+ Properties info
+)
+
+
+ |
+
+java.sql.DriverManager |
+
+
+
+
+Die erste Variante erwartet lediglich einen Connection-String als
+Argument, der in Form eines URL (Uniform Ressource Locator, siehe
+Abschnitt 40.1.1) übergeben
+wird. Der Connection-String besteht aus mehreren Teilen, die durch
+Doppelpunkte voneinander getrennt sind. Der erste Teil ist immer »jdbc«
+und zeigt an, dass es sich um einen JDBC-URL handelt. Der zweite Teil
+wird als Sub-Protokoll bezeichnet und gibt an, welcher Treiber
+verwendet werden soll. Die übrigen Teile sind treiberspezifisch.
+Connection-Strings für die JDBC-ODBC-Bridge beginnen immer mit
+»jdbc:odbc«, gefolgt von einem weiteren Doppelpunkt, nach
+dem der Name der ODBC-Datenquelle angegeben wird:
+
+
+con = DriverManager.getConnection("jdbc:odbc:DirDB");
+
+
+
+
+Die zweite Variante von getConnection
+erlaubt es, zusätzlich den Benutzernamen und das Passwort an
+die Datenbank zu übergeben. Das ist bei vielen Datenbanken erforderlich,
+um eine Verbindung aufbauen zu können. Bei der dritten Variante
+können zusätzlich mit Hilfe eines Properties-Objekts
+weitere, treiberspezifische Informationen übergeben werden. Welche
+Variante zu verwenden ist, muss der jeweiligen Treiberdokumentation
+entnommen werden.
+
+
+
+
+Wenn die Verbindung erfolgreich aufgebaut werden konnte, liefert getConnection
+ein Objekt, das das Interface Connection
+implementiert. Dieses Verbindungsobjekt repräsentiert die aktuelle
+Datenbanksitzung und dient dazu, Anweisungsobjekte zu erzeugen und
+globale Einstellungen an der Datenbank zu verändern. Das Connection-Objekt
+kann durch Aufruf von close
+explizit geschlossen werden. Die Verbindung wird automatisch geschlossen,
+wenn die Connection-Variable
+vom Garbage Collector zerstört wird.
+
+
+
+
+
42.2.2 Erzeugen von Anweisungsobjekten
+
+
+Alle Abfragen und Änderungen der Datenbank erfolgen mit Hilfe
+von Anweisungsobjekten. Das sind Objekte,
+die das Interface Statement
+oder eines seiner Subinterfaces implementieren und von speziellen
+Methoden des Connection-Objekts
+erzeugt werden können:
+
+
+
+
+
+
+Statement createStatement()
+
+PreparedStatement prepareStatement(String sql)
+
+CallableStatement prepareCall(String sql)
+
+
+ |
+
+java.sql.Connection |
+
+
+
+
+Die einfachste Form ist dabei das von createStatement
+erzeugte Statement-Objekt.
+Es kann dazu verwendet werden, unparametrisierte Abfragen und Änderungen
+der Datenbank zu erzeugen. Seine beiden wichtigsten Methoden sind
+executeQuery
+und executeUpdate.
+Sie erwarten einen SQL-String als Argument und reichen diesen an die
+Datenbank weiter. Zurückgegeben wird entweder ein einfacher numerischer
+Ergebniswert, der den Erfolg der Anweisung anzeigt, oder eine Menge
+von Datenbanksätzen, die das Ergebnis der Abfrage repräsentieren.
+Auf die beiden übrigen Anweisungstypen werden wir später
+zurückkommen.
+
+
+
+
+
+
+42.2.3 Datenbankabfragen
+
+
+Hat man ein Statement-Objekt
+beschafft, kann dessen Methode executeQuery
+verwendet werden, um Daten aus der Datenbank zu lesen:
+
+
+
+
+
+
+public ResultSet executeQuery(String sql)
+ throws SQLException
+
+
+ |
+
+java.sql.Statement |
+
+
+
+
+Die Methode erwartet einen SQL-String in Form einer gültigen
+SELECT-Anweisung und gibt ein Objekt
+vom Typ ResultSet
+zurück, das die Ergebnismenge repräsentiert. Als Argument
+dürfen beliebige SELECT-Anweisungen übergeben werden, sofern
+sie für die zugrunde liegende Datenbank gültig sind. Die
+folgende SQL-Anweisung selektiert beispielsweise alle Sätze aus
+der Tabelle dir, deren Feld
+did den Wert 7 hat:
+
+
+SELECT * FROM dir WHERE did = 7
+
+
+
+
+Das zurückgegebene Objekt vom Typ ResultSet
+besitzt eine Methode next,
+mit der die Ergebnismenge schrittweise durchlaufen werden kann:
+
+
+
+
+Nach dem Aufruf von executeQuery
+steht der Satzzeiger zunächst vor dem ersten Element,
+jeder Aufruf von next
+positioniert ihn auf das nächste Element. Der Rückgabewert
+gibt an, ob die Operation erfolgreich war. Ist er false,
+gibt es keine weiteren Elemente in der Ergebnismenge. Ist er dagegen
+true,
+konnte das nächste Element erfolgreich ausgewählt werden,
+und mit Hilfe verschiedener get...-Methoden
+kann nun auf die einzelnen Spalten zugegriffen werden. Jede dieser
+Methoden steht in zwei unterschiedlichen Varianten zur Verfügung:
+
+- Wird ein numerischer Wert n als Argument übergeben,
+so wird dieser als Spaltenindex interpretiert und der Wert der n-ten
+Spalte zurückgegeben. Wichtig: Anders als bei Arrays hat die
+erste Spalte den Index 1.
+
- Wird ein String
+als Argument übergeben, so wird er als Name interpretiert und
+der Wert der Spalte mit diesem Namen zurückgegeben. Diese Variante
+soll zwar marginal langsamer als die erste sein, ist aber weniger
+fehlerträchtig. Da der Aufruf nicht mehr von der Spaltenreihenfolge
+der Abfrage abhängt, ist ihr normalerweise der Vorzug zu geben
+(das klappt leider nicht immer, wie die Warnung am Ende von Abschnitt 42.4.5
+deutlich macht).
+
+
+
+Um dem Entwickler lästige Typkonvertierungen zu ersparen, gibt
+es alle getXXX-Methoden in unterschiedlichen
+Typisierungen. So liefert beispielsweise getString
+das gewünschte Feld als String,
+während getInt
+es als int
+zurückgibt. Wo es möglich und sinnvoll ist, werden automatische
+Typkonvertierungen durchgeführt; getString
+kann beispielsweise für nahezu alle Typen verwendet werden. Tabelle 42.1
+gibt eine Übersicht über die wichtigsten get-Methoden
+der Klasse ResultSet.
+In Tabelle 42.4 findet sich
+eine Übersicht der wichtigsten SQL-Datentypen.
+
+
+
+
+Tabelle 42.1: get-Methoden von ResultSet
+
+
+
+
+
+
+42.2.4 Datenbankänderungen
+
+
+Datenbankänderungen werden mit den SQL-Anweisungen INSERT INTO,
+UPDATE
+oder DELETE FROM
+oder den SQL-DDL-Anweisungen (Data Definition Language)
+zum Ändern der Datenbankstruktur durchgeführt. Im Gegensatz
+zu Datenbankabfragen geben diese Anweisungen keine Ergebnismenge zurück,
+sondern lediglich einen einzelnen Wert. Im Falle von INSERT INTO,
+UPDATE
+und DELETE FROM
+gibt dieser Wert an, wie viele Datensätze von der Änderung
+betroffen waren, bei DDL-Anweisungen ist er immer 0.
+
+
+Um solche Anweisungen durchzuführen, stellt das Interface Statement
+die Methode executeUpdate
+zur Verfügung:
+
+
+
+
+
+
+public int executeUpdate(String sql)
+ throws SQLException
+
+
+ |
+
+java.sql.Statement |
+
+
+
+
+Auch sie erwartet als Argument einen String mit einer gültigen
+SQL-Anweisung, beispielsweise:
+
+
+INSERT INTO dir VALUES (1, 'x.txt', 0)
+
+
+
+
+Könnte diese Anweisung erfolgreich ausgeführt werden, würde
+sie 1 zurückgeben. Andernfalls würde eine SQLException
+ausgelöst.
+
+
+
+
+
+
+
+Wenn SQL-Anweisungen fehlschlagen, lösen sie normalerweise eine
+Ausnahme des Typs SQLException
+aus. Das gilt sowohl, wenn keine Verbindung zur Datenbank zustande
+gekommen ist, als auch bei allen Arten von Syntaxfehlern in SQL-Anweisungen.
+Auch bei semantischen Fehlern durch falsche Typisierung oder inhaltlich
+fehlerhafte SQL-Anweisungen wird eine solche Ausnahme ausgelöst.
+SQLException
+ist eine Erweiterung der Klasse Exception
+und stellt folgende zusätzliche Methoden zur Verfügung:
+
+
+
+
+
+
+int getErrorCode()
+
+String getSQLState()
+
+SQLException getNextException()
+
+
+ |
+
+java.sql.SQLException |
+
+
+
+
+Mit getErrorCode
+kann der herstellerspezifische Fehlercode abgefragt werden, getSQLState
+liefert den internen SQL-Zustandscode. Etwas ungewöhnlich ist
+die Methode getNextException,
+denn sie unterstützt die Verkettung von Ausnahmen. Jeder
+Aufruf holt die nächste Ausnahme aus der Liste. Ist der Rückgabewert
+null,
+gibt es keine weiteren Ausnahmen. Code zum Behandeln einer SQLException
+könnte also etwa so aussehen:
+
+
+
+
+
+
+
+
+001 ...
+002 catch (SQLException e) {
+003 while (e != null) {
+004 System.err.println(e.toString());
+005 System.err.println("SQL-State: " + e.getSQLState());
+006 System.err.println("ErrorCode: " + e.getErrorCode());
+007 e = e.getNextException();
+008 }
+009 }
+
+ |
+
+
+
+Listing 42.1: Behandeln einer SQLException