83kB - Praktische Informatik

Werbung
JDBC (Stichworte)
Udo Kelter
19.12.2011
Zusammenfassung dieses Lehrmoduls
JDBC (Java Database Connectivity) ist eine Schnittstelle, über
die von Java-Programmen aus auf die Inhalte relationaler Datenbanken zugegriffen werden kann. Dieses Lehrmodul stellt die wichtigsten
Funktionen vor. Insb. wird die Frage beantwortet, wie mit einer
typsicheren Sprache wie Java die Ergebnisse von Abfragen, deren Typ
man nicht statisch bestimmen kann, verarbeitet werden können.
Vorausgesetzte Lehrmodule:
obligatorisch:
-
Einführung in SQL
Stoffumfang in Vorlesungsdoppelstunden:
1
1.0
JDBC (Stichworte)
2
Inhaltsverzeichnis
1 Motivation
1.1 JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
2 Aufbau einer Verbindung zum Datenbankserver
2.1 JDBC-Treiber laden . . . . . . . . . . . . . . . . . . . . . . .
2.2 Connection-Objekt erzeugen . . . . . . . . . . . . . . . . . . .
4
4
4
3 SQL-Statements
3.1 SQL-Statement-Objekte erzeugen . . . . . . . . . . . . . . . .
3.2 executeUpdate . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 executeQuery . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
4
5
6
4 ResultSets als Abfrageergebnisse
4.1 ResultSet als lineare Liste . . . . . .
4.2 Positionierbare ResultSets . . . . . .
4.3 Auslesen eines Tupels . . . . . . . .
4.4 Automatisch aktualisierte ResultSets
.
.
.
.
6
6
6
6
7
5 Änderbare ResultSets
5.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Ändern eines Tupels . . . . . . . . . . . . . . . . . . . . . . .
8
8
8
6 Vorübersetzte Statements
9
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7 Fehlerbehandlung
10
Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
10
c
2011
Udo Kelter
Stand: 19.12.2011
Dieser Text darf für nichtkommerzielle Nutzungen als Ganzes und unverändert in elektronischer oder
gedruckter Form beliebig weitergegeben werden und in WWW-Seiten, CDs und Datenbanken aufgenommen werden. Jede andere Nutzung, insb. die Veränderung und Überführung in andere Formate, bedarf
der expliziten Genehmigung. Die jeweils aktuellste Version ist über http://kltr.de erreichbar.
JDBC (Stichworte)
1
3
Motivation
praktisches Problem: Zugriff auf eine relationale Datenbank von einem
Programm aus; Detailprobleme:
-
Aufbau und Überwachung einer Verbindung zum Datenbankserver
-
Konversion von Daten in der Datenbank und in den Laufzeitobjekten der jeweiligen Programmiersprache
speziell bei Abfragen: Darstellung einer (Ergebnis-) Relation als
Laufzeit-Datenstruktur
-
Gestaltung geeigneter und leicht bedienbarer APIs
Fehlerbehandlung
1.1
JDBC
JDBC (Java Database Connectivity) ...
-
“is the industry standard for database-independent connectivity
between the Java programming language and a wide range of SQL
databases and other tabular data sources, such as spreadsheets or
flat files.
-
The JDBC API provides a call-level API for SQL-based database
access.
(von:
)
http://www.oracle.com/technetwork/java/javase/jdbc/index.html
→ jeder Hersteller eines relationalen DBMS kann/sollte eine Implementierung des JDBC APIs mitliefern
wird Treiber (driver) genannt
(Analogie zum Anschluß von Plattenlaufwerken)
→ ggf. in der Doku danach suchen
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
2
2.1
4
Aufbau einer Verbindung zum Datenbankserver
JDBC-Treiber laden
Treiber wird identifiziert durch Paket- und Klassennamen,
Beispiel:
org.postgresql.Driver
Laden:
Class.forName(driver class);
Beispiel:
Class.forName("org.postgresql.Driver");
2.2
Connection-Objekt erzeugen
Verbindungen werden durch Connection-Objekte repräsentiert. Deklaration:
Connection con = null;
Aufbau der Verbindung:
con = DriverManager.getConnection(db, user, passw);
Parameter von getConnection:
db
Angabe der Datenbank in folgender Syntax:
protokoll://rechnername/dateipfad
Beispiel:
jdbc:postgresql://pi81.informatik.uni-siegen.de/dbs1
user
Benutzername
passw Passwort
3
3.1
SQL-Statements
SQL-Statement-Objekte erzeugen
Anweisungen werden durch Statement-Objekte repräsentiert.
Deklaration:
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
5
Statement stmt;
mehrere Schritte trennen:
1. Statement-Objekt erzeugen und initialisieren
2. die enthaltene Anweisung eintragen
3. Anweisung ausführen (ggf. mehrfach)
Statement-Objekt initialisieren:
stmt = con.createStatement();
im Zustand des Statement-Objekts ist vermerkt, zu welcher Verbindung es gehört!
einfachste Formen, um Anweisungen aufzubauen und gleich auszuführen:
ResultSet result = stmt.executeQuery("SELECT...");
int
num =
stmt.executeUpdate("INSERT ...");
3.2
executeUpdate
allgemeines Kommando für alle SQL-Kommandos, die eine Datenbank
ändern (insb. create table, insert, delete, ...):
int executeUpdate(String sql)
Beispiel: int num = stmt.executeUpdate("INSERT ...");
Zurückgegebener Wert:
-
Zahl der eingefügten / gelöschten / geänderten Tupel
0 bei create table und u.ä. Kommandos
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
3.3
6
executeQuery
eigenes Kommando für Abfragen:
ResultSet executeQuery(String sql)
Beispiel:
ResultSet result = stmt.executeQuery("SELECT...");
4
4.1
ResultSets als Abfrageergebnisse
ResultSet als lineare Liste
einfachste Form der Erzeugung eines ResultSets:
ResultSet result = stmt.executeQuery("SELECT...");
erzeugt eine lineare Liste von Tupeln (rows)
durchlaufen (max. 1*) mit Operation next:
while(result.next()) { verarbeite aktuelles Tupel }
4.2
Positionierbare ResultSets
statt als lineare Liste können ResultSets als beliebig positionierbare
(“scrollbare”) Kollektion erzeugt werden; hierzu:
stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE);
result = stmt.executeQuery("SELECT...");
Positionierungsoperationen (next, previous, first, last,
relative, absolute) s. JDBC-Tutorial, Abschnitt “Cursors”.
4.3
...
Auslesen eines Tupels
Problem: Typ der Ergebnisrelation ist i.a. statisch (zur Übersetzungszeit) nicht bekannt – Java ist aber eine typsichere Sprache
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
7
Lösung: die Operationen getInt, getString usw.
-
-
i.a. getXXX, worin XXX ein Typname ist
liefern einen Wert vom Typ XXX zurück
→ : Entwickler muß den Typ des Attributs kennen
Vorsicht: teilweise implizite Konversionen!
beziehen sich auf das aktuelle Tupel
jeweils zwei Varianten, die das gewünschte Attribut verschieden identifizieren:
-
getXXX(string): anhand des Namens
getXXX(int): anhand der Position (1,...)
Beispiele:
name = result.getString("Vorname");
plz = result.getInt(5);
ca. 15 weitere s.
http://docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html
4.4
Automatisch aktualisierte ResultSets
Problem: ein ResultSets ist eine Kopie der selektierten Daten zum
Zeitpunkt seiner Erstellung. – Originaldaten können sich während der
Existenz des ResultSets ändern.
Wunsch: der ResultSets soll automatisch an solche Änderungen angepaßt werden
Lösung: “sensitive” ResultSets
stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE);
result = stmt.executeQuery("SELECT...");
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
5
8
Änderbare ResultSets
5.1
Motivation
Problem: oft will man einen ResultSets durchlaufen und jedes Tupel
sofort verändern.
Beispiel: erhöhe alle Preise eines Warenbestands um 5%.
Lösung 1: jedesmal ein update-Kommando - sehr umständlich und
ineffizient
bessere Lösung 2: Änderbare ResultSets1
hierzu: concurrency level UPDATABLE:
stmt = con.createStatement(
ResultSet.CONCUR_UPDATABLE);
result = stmt.executeQuery("SELECT...");
(Vorgabewert für den concurrency level: READ ONLY)
5.2
Ändern eines Tupels
i.w. analog zu den getXXX-Operationen:
Operationen updateInt, updateString, usw.
-
beziehen sich auf das aktuelle Tupel
heißen i.a. updateXXX, worin XXX ein Typname ist
1. Parameter: Name oder Nummer des gewünschten Attributs
2. Parameter: neuer Wert des Attributs
Vorsicht: Konversionen!
Rückgabewert void
Beispiele:
1
nach einer Änderung ist der Begriff ResultSet eigentlich nicht mehr korrekt.
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
9
result.updateString("Vorname", "Hans");
result.updateInt(5,57076);
ca. 15 weitere s.
http://docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html
6
Vorübersetzte Statements
Problem: Übersetzen eines textuellen SQL-Kommandos ist relativ aufwendig (Syntax, Prüfung aller Bezeichner, ...); Aufwand vermeidbar,
wenn immer wieder fast gleiche SQL-Kommandos ausgeführt werden.
Lösung: Prepared Statements. Beispiel:
String insertcmd = "INSERT INTO lieferungen "
+ "(Kundennummer, Lieferadresse, Betrag, Datum) "
+ "VALUES ( ?, ?, 25, 31.12.2011 )"
PreparedStatement psInsertLfg;
psInsertLfg = con.prepareStatement(insertcmd);
Vorübersetzen mit prepareStatement:
-
SQL-String: “may contain one or more ’ ?’ IN parameters”
findet schon hier Syntaxfehler
Nachliefern der Parameter mit setXXX-Kommandos:
psInsertLfg.setInt
(1, 181917);
psInsertLfg.setString (2, "Schulte, Maria");
1. Parameter: Nr. des offenen Parameters
2. Parameter: Wert gem. Wertebereich XXX
Ausführen des Kommandos nach Füllen aller Parameter:
psInsertLfg.executeUpdate();
weitere Details s.
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
c
2011
Udo Kelter
Stand: 19.12.2011
JDBC (Stichworte)
7
10
Fehlerbehandlung
Alle Datenbankzugriffe müssen in try/catch-Blöcken gekapselt werden.
Zugriffsoperationen werfen exceptions vom Typ SQLException.
Details s. http://docs.oracle.com/javase/tutorial/jdbc/basics/sqlexception
Operationen auf SQLException:
getMessage liefert eine verbale Beschreibung des Fehlers
getSQLState() liefert einen Fehlercode gemäß ANSI-92-Standard
getErrorCode() liefert einen herstellerspezifischen Fehler-Code
i.a. können mehrere SQLExceptions bei einen Datenbankzugriff auftreten, ferner mehrere Warnungen
Auslesen der Liste der SQLExceptions bzw. Warnungen s.
http://docs.oracle.com/javase/tutorial/jdbc/basics/sqlexception.html
Literatur
[SQL] Kelter, U.: Lehrmodul “Einführung in SQL”; 2005
c
2011
Udo Kelter
Stand: 19.12.2011
Herunterladen