Chapter 9 - BFH-TI Staff

Werbung
JDBC
Pierre Fierz
Chapter 9
SQL in
Programmiersprachen
JDBC
Java Database
Connectivity JDBC
Lecture Datenbanken
24.04.2014
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
Pierre Fierz
Berner Fachhochschule
Technik und Informatik
9.1
Contents
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.2
Outline
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.3
SQL in Programmiersprachen
JDBC
Pierre Fierz
• Für grössere Applikationen ist es nötig SQL in einer
Programmiersprache einzubetten.
• Diese Koppelung wird als Wirtssprachen-Koppelung
bezeichnet.
• Dabei sind die folgenden Voraussetzungen nötig:
• Die Schutzmechanismen der Datenbank müssen auch für
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
ein Programm gelten.
• Fremdschlüsselbedingung, Assertion usw. müssen
eingehalten werden.
• Innerhalb der SQL-Befehle müssen Parameter (Variablen)
der Wirtssprache verwendet werden können.
• Es muss klar definiert werden, wie die Datentypen der
Datenbank in Datentypen der Wirtssprache übersetzt
werden.
9.4
SQL in Programmiersprachen (2)
JDBC
Pierre Fierz
SQL in
Programmiersprachen
• Es gibt mehere Möglichkeiten SQL in einer
Programmiersprache einzubinden.
• Wir werden hier die Java Datenbankanbindung JDBC
anschauen.
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Eine weitere Möglichkeit ist embedded SQL, das für
beliebige Sprachen standardisiert ist.
• Ferner existieren auch objektrelationale Systeme wie Java
Persitence API (JPA).
9.5
Outline
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.6
Was ist JDBC
JDBC
Pierre Fierz
• JDBC = Java DataBase Connectivity ist mit ODBC (Open
Database Connectivity) von Microsoft vergleichbar.
• JDBC ist ein low-level oder call-level API um
•
•
•
•
Die Verbindung zu einer Datenbank herzustellen
SQL-Befehle abzusetzen
Resultate zu analysieren und zu verarbeiten
Information über die Datenbank bereitzustellen.
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• JDBC ermöglicht einen produktunabhängigen
Datenbankzugriff.
• JDBC ist eine Basis für high-level API’s, die das Arbeiten
mit SQL vollständig verstecken und z.B. direkt
Java-Objekte verwalten.
9.7
JDBC
JDBC Package-Struktur
Pierre Fierz
• JDBC besitzt die folgende Package-Struktur
SQL in
Programmiersprachen
JDBC Package
Java Database
Connectivity JDBC
UserPackage
<<implements>>
<<uses>>
java.sql
VendorPackage
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
• java.sql: Dieses Package gehört ab Java 1.1 zum
Meta-Informationen
Standard API.
• VendorPackage: Dieses Package enthält für jedes
Interface von java.sql eine entsprechende
Implementationsklasse.
• Es stellt die eigentliche Funktionalität zur Verfügung und
wird von Datenbank- oder Drittherstellern vertrieben.
• UserPackage: Dieses Package erzeugt und benützt
Variablen der verschiedenen Interfaces von java.sql.
9.8
JDBC
Das Package java.sql
Pierre Fierz
• Nachfolgend sind die wichtigsten Interfaces und Klassen
des Packages java.sql dargestellt.
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
java.sql
<<interface>>
ResultSet
<<interface>>
<<creates>>
Statement
<<class>>
<<interface>>
DriverManager
Driver
<<creates>>
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
<<creates>>
<<creates>>
<<interface>>
<<interface>>
ResultSetMetaData
PreparedStatement
<<interface>>
<<interface>>
Connection
<<creates>>
<<creates>>
DatabaseMetaData
<<interface>>
CallableStatement
<<creates>>
9.9
Das Package java.sql (2)
JDBC
Pierre Fierz
SQL in
Programmiersprachen
• Damit der Java-Code unabhängig von der verwendeten
Datenbank ist gelten für die Erzeugung von Objekten die
folgenden Regeln:
• Objekte von Implementationsklassen im VendorPackage
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
werden niemals direkt mit new erzeugt.
• Dazu existieren Get- oder Create-Methoden
• Die Namen der Implementationsklassen bleiben dem
Anwender Package verborgen.
• Einzige Ausnahme ist der Name der Driverklasse.
9.10
Driver Interface
JDBC
Pierre Fierz
• Die Aufgabe des Drivers ist, eine Verbindung zwischen
dem Java-Programm und der Datenbank herzustellen.
• Eine Driverimplementation muss eine “static section”
enthalten, die die folgenden Aufgaben übernimmt:
1
2
Kreieren einer Instanz des Drivers
Registrieren des Drivers beim Drivermanager
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Die gewünschten Drivers können mit der Methode
Class.forname geladen werden (der Driver muss im
Classpath sein).
• Ab JDBC Version 4.0 muss der Driver nicht mehr explizit
geladen werden
• Die Klasse Drivermanager ist in der Lage den Driver zu
finden und zu laden.
9.11
DriverManager Klasse
• Diese Klasse enthält nur statische Methoden.
• Für den Anwender ist die Methode getConnection, die die
Verbindung mit der Datenbank aufnimmt am wichtigsten.
• Der Methode muss eine sogennante JDBC URL
übergeben werden.
• An Hand dieser URL weiss der Drivermanager welche
Datenbank geöffnet werden muss.
• Die JDBC URL hat das folgende Format:
jdbc:<subprotocol>:<subname>
• <subprotocol> – ist der offizielle Name eines Drivers.
Subprotokolle können von Driver Herstellern bei Javasoft
registriert werden.
• <subname> – dient dazu, die Datenbank zu identifizieren.
Der genaue Aufbau dieses Teiles ist Herstellerabhängig.
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
Verbindung zu einer Datenbank aufnehmen
Connection con = DriverManager.getConnection(
"jdbc:mysql://db.bfh.ch/fierzdb"
Name, Passwort)
9.12
Statement und Resultset Interface
JDBC
Pierre Fierz
• Mit Hilfe eines Connection Objekts können Statement
Objekte kreiert werden.
• Statement dienen dazu, SQL-Befehle der Datenbank zu
senden.
• Die drei folgenden Methoden sind besonders wichtig:
1
2
3
executeQuery: für SELECT
executeUpdate: für INSERT, UPDATE, DELETE, CREATE,
DROP usw.
execute: für SQL-Befehle, die mehr als ein Resultat liefern
(stored Procedures);
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Die Methode executeQuery gibt ein Objekt des Typs
Resultset zurück.
• Ein Resultset ist die Implementation einer Relation
• Die Methode next iteriert durch alle Tupel der Relation
hindurch.
• Mit den Methoden get<Datatype> kann der Wert der
einzelnen Attribute ermittelt werden.
9.13
Metainformationen
JDBC
Pierre Fierz
• Mit dem Interface DatabaseMetadata können
Informationen über das Datenbankschema geholt werden
•
•
•
•
Tabellen
Attribute
Schlüssel
usw.
• Mit dem Interface ResultSetMetaData können
Informationen über ein Objekt des Typs ResultSet
gewonnen werden.
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Dies wird benutzt, wenn das Resultat eines Queries zur
Kompilationszeit nicht bekannt ist.
• Folgende Informationen sind verfügbar:
• Anzahl Attribute
• Name der Attribute
• Tabelle der Attribute
• Datentyp
• usw.
9.14
Metainformationen (2)
JDBC
Pierre Fierz
• Die Klasse DriverPropertyInfo dient dazu, Informationen
über einen bestimmten Driver zu erhalten.
• Zum Beispiel kann man so erfahren, welche Parameter
beim Öffnen der Datenbank (connect) notwendig sind
(user, password usw.).
• Es ist auch möglich bein Aufbau der Connection gewisse
Einstellungen des Drivers zu verändern.
• Bevor die Informationen zur Verfügung stehen, muss der
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
Driver geladen werden.
Hohlen der Driver Properties
try {
/* Laden des Drivers ab JDBC 4.0 nicht mehr noetig */
Class.forName("com.mysql.jdbc.Driver");
/* Driver hohlen */
Driver dv = DriverManager.getDriver("jdbc:mysql://a/b");
/* Hohlen der Driverproperties */
return dv.getPropertyInfo(url, po);
} catch (SQLException e) {
;
}
9.15
Weitere Klassen
JDBC
Pierre Fierz
SQL in
Programmiersprachen
• Neben den Klassen und Interfaces in der Abbildung
existieren noch die folgenden Klassen im Package java.sql
• Klassen für das Exceptionhandling
• SQLException und Subklassen
• SQLWarning
• DataTruncation
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Date, Time, TimeStamp: Diese Klassen garantieren die
Kompatibilität zwischen Datenbank und Java bezüglich
Zeit und Datum.
• Types: Diese Klasse enthält Konstanten, welche die
generischen SQL-Typen definieren
9.16
Outline
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.17
JDBC Beispiele
JDBC
Pierre Fierz
• Das nächste Beispiel zeigt der Aufbau der Verbindung zur
Datenbank
• Das JDBC Vendopackage muss im Classpath vorhanden
sein.
Verbindung zur Datenbank aufnehmen
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Connection con = null;
Meta-Informationen
// Verbindung mit der Datenbank aufnehmen. Mit Hilfe
// des Subprotokolls "mysql" wird der
// Drivermanager wissen, dass die Verbindung zu einer
// Mysql-Datenbank aufgenommen werden muss.
//
// Bei Mysql ist die Angabe von User und Passwort
// notwendig.
try {
con = DriverManager.getConnection(
"jdbc:mysql://db.bfh.ch/fierzdb",
user, passwd );
} catch (SQLException e) {
// Verbindung kann nicht aufgenommen werden.
System.exit(1);
}
9.18
JDBC Beispiele (2)
JDBC
Pierre Fierz
• Das nächste Beispiel zeigt ein einfaches Select Beispiel.
Absetzen eines Select Statements
// Beispiel SELECT Befehl
try {
Statement stmt = con.createStatement();
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery(
"SELECT mNr, Name, Ort, Plz " +
"FROM Mitarbeiter");
while (rs.next()) {
System.out.print(rs.getInt(1) + " / " +
rs.getString(2) + " / ");
// Es ist auch möglich mit dem Namen des Feldes
// auf die Daten zuzugreifen.
System.out.println(rs.getString("Ort") + " " +
rs.getString("Plz"));
}
// Statement explizit schliessen, damit die
// Datenbankresourcen sofort freigegeben werden und
// nicht erst bei einer Garbagecollection.
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.19
JDBC Beispiele (3)
JDBC
Pierre Fierz
• Das nächste Beispiel zeigt einen Insert Befehl
Ausführen eines Inserts
// UPDATE Befehle
try {
Statement stmt = con.createStatement();
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
// Absetzen eines Inserts. Dazu muss die Methode
// executeUpdate verwendet werden.
int changes = stmt.executeUpdate(
"INSERT INTO Projekt (pNr, PName, aNr, Standort) " +
"VALUES (101, ’Neues Projekt’, 3, ’Bern’)");
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
9.20
JDBC Beispiele (4)
JDBC
Pierre Fierz
• Wenn der Benutzer die entsprechenden Rechte besitzt,
können auch DDL Befehle ausgeführt werden.
Kreieren einer Tabelle
// Kreieren einer neuen Tabelle
try {
Statement stmt = con.createStatement();
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
stmt.executeUpdate("CREATE TABLE kunde (" +
"kNr
INTEGER NOT NULL, " +
"KName VARCHAR(30) NOT NULL, " +
"Ort
VARCHAR(30) NOT NULL," +
"PRIMARY KEY (kNr))");
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
9.21
JDBC Beispiele (5)
JDBC
Pierre Fierz
• Prepared Statements dienen dazu, oft verwendete Befehle
zu beschleunigen und gleichzeitig die Parameterübergabe
zu vereinfachen
Insert mit einem prepared Statement
// Prepared Statements mit Parameteruebergabe.
// erlaubt es ein SQL-Befehl mehrmals zu verwenden.
try {
PreparedStatement stmt = con.prepareStatement(
"INSERT INTO Projekt " +
"(pNr, PName, paNr, PStandort) VALUES (?,?,?,?)");
// Parameter uebergeben
stmt.setInt(1, 25);
stmt.setString(2, "Coop Baustelle");
stmt.setInt(3, 4);
stmt.setString(4, "Belp");
// Befehl ausfuehren
int changes = stmt.executeUpdate();
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.22
JDBC Beispiele (6)
• Um herauszufinden ob ein Attribut einen Nullwert enthält,
muss zuerst das entsprechende Attribut mit der Methode
get<Datatyp> gelesen werden.
• Anschliessend kann mit der Klassenmethode
ResultSet.wasNull() gefragt werden, ob das Resultat ein
Nullwert ist.
Behandlung von NULL Werten
// Behandlung von Nullvalues
try {
Statement stmt = con.createStatement();
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery(
"SELECT mNr, Name, Vorgesetzter " +
"FROM Mitarbeiter");
while (rs.next()) {
int vorgesetzter = rs.getInt(3);
if (rs.wasNull() == true)
System.out.println("Mitarbeiter " + rs.getInt(1) + ". "
+ rs.getString(2) + " hat keinen Vorgesetzten");
}
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
9.23
JDBC Beispiele (7)
• In einem Resultset kann man auch Rückwärtsscrollen und
JDBC
Pierre Fierz
den Cursor absolut oder relativ positionieren.
Scrollen im Resultset
// Beispiel Scroll im Resultset
try {
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery(
"SELECT * FROM Mitarbeiter " +
"ORDER BY mNr");
// Lieferanten in der Umgekehrten Reihenfolge Ausgeben
rs.afterLast();
while (rs.previous()) {
System.out.print(rs.getString("name"));
}
// Auf 7. Tupel positionieren
if(rs.absolute(7)) {
// Nun 5 Tupel rückwaerts
rs.relative(-5);
}
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.24
JDBC Beispiele (8)
JDBC
Pierre Fierz
• Man kann Tupel in einem Resultset auch verändern und in
der DB zurückspeichern.
Update von Tupel im Resultset
// Beispiel Update im Resultset
try {
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery(
"SELECT * FROM Mitarbeiter " +
"ORDER BY mNr");
// Setzen auf tupel sieben und Ort aendern
if (rs.absolute(7)) {
rs.updateString("Ort", "Genf");
rs.updateRow();
}
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
9.25
JDBC Beispiele (9)
• Im nächsten Beispiel wird ein neues Tupel in die
Datenbank eingefügt.
Insert von Tupel im Resultset
// Beispiel Update und Insert im Resultset
try {
Statement stmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery("SELECT * FROM Projekt " +
"ORDER BY pNr");
// Einfuegen eines Projektes
rs.moveToInsertRow();
// Daten abfuellen
rs.updateInt("pNr", 102);
rs.updateString("PName", "Coop Baustelle");
rs.updateInt("paNr", 2);
rs.updateString("Standort", "Belp");
// Lieferant zurueckschreiben
rs.insertRow();
// Auf Urspruengliche Position zurueck
rs.moveToCurrentRow();
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.26
Outline
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.27
Aufruf von Prozeduren und Funktionen
• Die Syntax für den Aufruf einer Prozedur hat die folgende
Form:
SQL Syntax (JDBC call)
<jdbc-call> ::= {CALL <procname> ([<arg> [, <arg>]. . . ])}
<arg>
::= {? | <literal>}
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Aufruf einer Prozedur mit ouput Parameter
Meta-Informationen
try {
// Aufrufen der Prozedur "Stundenproc"
CallableStatement cstmt = con.prepareCall(
"{CALL Stundenproc(?, ?)}");
// Parameter nummer 1 setzen (Projektnummer)
cstmt.setInt(1,2);
// Rueckgabeparameter (Parameter 2) registrieren
cstmt.registerOutParameter(2, Types.FLOAT);
// Ausfuehren der Funktion
cstmt.execute();
// Lesen und ausgeben des Resultats
System.out.println(cstmt.getFloat(2));
} catch (Exception e) {
System.out.println("*** " +e);
}
9.28
Aufruf von Prozeduren und Funktionen (2)
• Die Syntax für den Aufruf einer Funktion hat die folgende
Form:
SQL Syntax (JDBC call)
<jdbc-funcall> ::= {? = CALL <procname> ([<arg> [, <arg>]. . . ])}
<arg>
::= {? | <literal>}
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Aufruf einer Funktion
Meta-Informationen
try {
// Aufrufen der Funktion "Stundenfunc"
CallableStatement cstmt = con.prepareCall(
"{? = CALL Stundenfunc(?)}");
// Parameter nummer 2 setzen (ProjektNummer)
cstmt.setInt(2,2);
// Rueckgabewert (Parameter 1) registrieren
cstmt.registerOutParameter(1, Types.FLOAT);
// Ausfuehren der Funktion
cstmt.execute();
// Lesen und ausgeben des Resultats
System.out.println(cstmt.getInt(1));
} catch (Exception e) {
System.out.println("*** " +e);
}
9.29
Prozeduren und Resultsets
JDBC
Pierre Fierz
• Prozeduren können auch Resultsets zurückgeben.
• Dazu genügt es in der Prozedur ein normales Select
Statement zu schreiben.
Prozedur mit Resultset
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
CREATE PROCEDURE AnzProj()
BEGIN
SELECT
a.aNr, a.AName, COUNT(*)
FROM
Abteilung a JOIN Projekt p
ON a.aNr = p.paNr
GROUP BY a.aNr, p.AName;
END
9.30
Prozeduren und Resultsets (2)
JDBC
Pierre Fierz
• Die Prozedur kann nun in einem Programm aufgerufen
werden.
• Anschliessend kann der Resultset abgearbeitet werden.
Aufruf einer Prozedur mit Resultset
try {
// Aufrufen der Funktion "AnzProj"
CallableStatement cstmt =
con.prepareCall("{call AnzProj()}");
// Ausfuehren der Funktion
if (cstmt.execute()) {
// ResultSet hohlen und lesen
ResultSet rs = cstmt.getResultSet();
while (rs.next()) {
System.out.println(rs.getInt(1) + " " +
rs.getString(2) + " " +
rs.getInt(3));
}
}
} catch (Exception e) {
System.out.println("*** " +e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.31
Prozeduren und Resultsets (3)
JDBC
Pierre Fierz
• In manchen DBMS (darunter auch Mysql) ist es möglich,
dass eine Routine mehrere ResultSets zurückgibt.
• Die Anzahl Resultset ist gleich der Anzahl Select
Statements in der Prozedur.
Prozedur mit zwei Resultsets
CREATE PROCEDURE AnzProj1()
BEGIN
-- Erstes ResultSet
SELECT
a.aNr, a.AName, COUNT(*)
FROM
Abteilung a JOIN Projekt p
ON a.aNr = p.paNr
GROUP BY a.aNr, p.AName;
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
-- Zweites ResultSet
SELECT a.aNr, a.AName, 0
FROM
Abteilung a
WHERE NOT EXISTS (SELECT *
FROM Projekt p
WHERE a.aNr = p.paNr);
END
9.32
Prozeduren und Resultsets (4)
JDBC
Pierre Fierz
• Das nächste Programmfragment ruft die Prozedur auf und
listet anschliessend beide Resultate aus.
Aufruf einer Prozedur mit mehreren Resultsets
try {
// Aufrufen der Funktion "AnzProj1"
CallableStatement cstmt = con.prepareCall(
"{call AnzProj1()}");
// Ausfuehren der Funktion
if (cstmt.execute()) {
do {
// ResultSet hohlen und lesen
ResultSet rs = cstmt.getResultSet();
while (rs.next()) {
System.out.println(rs.getInt(1) + " " +
rs.getString(2) + " " +
rs.getInt(3));
}
} while(cstmt.getMoreResults());
}
} catch (Exception e) {
System.out.println("*** " +e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.33
Outline
JDBC
Pierre Fierz
1 SQL in Programmiersprachen
2 Java Database Connectivity JDBC
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
3 Programmieren mit JDBC
4 SQL-ROUTINEN und JDBC
5 Meta-Informationen
9.34
Metainformationen
JDBC
Pierre Fierz
SQL in
Programmiersprachen
• Es gibt bei der Programmierung Probleme, die nicht mit
den bisherigen Methoden gelöst werden können.
• Insbesondere sind bei generischen Programmen die SQL
Befehle zur Kompilationszeit nicht bekannt.
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
• Mit der Klasse ResultsetMetaData kann zur Laufzeit der
Aufbau eines Resultsets bestimmt werden.
• Mit der Klasse DatabaseMetaData können beliebige
Informationen über das Datenbankschema gewonnen
werden.
9.35
ResultSetMetaData
JDBC
Pierre Fierz
• Das nächste Beispiel zeigt, wie ein Resultset analysiert
werden kann.
Scrollen im Resultset
// Beispiel fuer die Benutzung von ResultSetMetaData
try {
Statement stmt = con.createStatement();
// Aufbauen eines Queries
ResultSet rs = stmt.executeQuery(
"SELECT * FROM Mitarbeiter m natural join MitProj mp " +
" natural join Projekt");
// Metadaten hohlen
ResultSetMetaData rsm = rs.getMetaData();
// Anzahl Kolonnen bestimmen
int cols = rsm.getColumnCount();
while (rs.next()) {
// Name, Datentyp und Inhalt der einzelnen Kolonnen
// abfragen und ausgeben
for (int i = 1; i <= cols; i++) {
String cna = rsm.getColumnName(i),
cco = rs.getString(i);
int
cty = rsm.getColumnType(i);
System.out.println(cna + " (" + cty + "): " + cco);
}
}
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.36
DatabaseMetaData
• Das nächste Beispiel zeigt, wie Informationen über die
einzelnen Relationenschematas der Datenbank gewonnen
werden kann.
Scrollen im Resultset
JDBC
Pierre Fierz
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
// Beispiel fuer die Benutzung von DatabaseMetaData
try {
DatabaseMetaData dbmd = con.getMetaData();
// Information ueber alle Tabellen
String [] s = {"TABLE"};
ResultSet rs1 = dbmd.getTables("firma", null, "%", s);
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
while (rs1.next()) {
String tn = rs1.getString("TABLE_NAME");
// Einlesen aller Attribute der Tabelle
ResultSet rs2 = dbmd.getColumns("firma", null, tn, null);
while (rs2.next()) {
// Ausgeben einiger Informationen
System.out.println(rs2.getString("COLUMN_NAME") +
" / " + rs2.getString("TYPE_NAME") +
"(" + rs2.getInt("COLUMN_SIZE") + ")");
}
}
} catch (Exception e) {
System.out.println(e);
}
9.37
Die execute Methode
JDBC
Pierre Fierz
SQL in
Programmiersprachen
• Bei generischen Programmen weiss man oft nicht, ob ein
SQL Befehl ein Query oder ein Update ist.
• In diesem Fall wird man die execute Methode benutzen
• Ist der Rückgabewert true, so war der Befehl ein Query
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
und der Resultset kann mit der Methode getResulSet()
bestimmt werden.
• Ist der Rückgabewert false, so war der Befehl kein Query.
In diesem Fall kann mit der Methode getUpdateCount() die
Anzahl veränderter Tupel ermittelt werden.
9.38
Die execute Methode (2)
JDBC
Pierre Fierz
• Im folgenden Beispiel kann ein beliebiges SQL Statement
auf der Commando Zeile eingegeben werden.
Scrollen im Resultset
// Beispiel fuer die Benutzung von execute und
// ResultSetMetaData
try {
Statement stmt = con.createStatement();
// SQL-Statement ist im 4. Argument der Kommandozeile:
// Ausfuehren des Statements
if (stmt.execute(args[3])) {
// Das Statement ist ein Query wir muessen also
// die Resultset und die Metadaten hohlen
ResultSet rs = stmt.getResultSet();
ResultSetMetaData rsm = rs.getMetaData();
// Weitere Verarbeitung
// ...
} else {
// Kein Query anzahl veraenderter Tuple herausgeben
System.out.println("Update Count: " +
stmt.getUpdateCount());
}
stmt.close();
} catch (SQLException e) {
System.out.println(e);
}
SQL in
Programmiersprachen
Java Database
Connectivity JDBC
Programmieren mit
JDBC
SQL-ROUTINEN und
JDBC
Meta-Informationen
9.39
Herunterladen