JAVA zum Zugriff auf Datenbanken

Werbung
JAVA zum Zugriff auf
Datenbanken
JDBC
Sven Frimont
15.01.2001
1.
2.
3.
4.
5.
6.
7.
Überblick
Treiber und Datenbankverbindung
Ausführung von SQL-Anfragen
ResultSet: Ergebnisse von Anfragen
Abbildung von SQL-Typen in Java
DBMS-Unabhängige Programmierung
Vorteile der Programmierung einer
Datenbankanwendung in Java
JDBC...
• ...steht (inoffiziell) für Java Database
Connectivity
• ...gehört seit Java 1.1 zur Standard-API von Java
• ...ermöglicht Java-Programmen einen
Zugriff auf relationale DBMS
• ...besteht aus Klassen und Interfaces
Historie von JDBC
• Ab Java 1.1 ist JDBC Bestandteil des
Standard-API von Java
• Die aktuelle Version: JDBC 2.1
• Spezifikation im ‚Alpha Draft‘: JDBC 3.0
Wie können Programmiersprache
und ein DBMS gekoppelt werden?
• Prozedurale Schnittstelle
• Spracherweiterungen / neue Sprachentwicklungen
• Einbettung einer Datenbanksprache in die
Programmiersprache
• statisch:
Datenbank-Anweisungen müssen zur Übersetzungszeit
feststehen
• dynamisch:
Ermöglicht Konstruktion der Datenbank-Anweisungen
zur Laufzeit
Wie sind Java und ein DBMS durch
JDBC gekoppelt?
• JDBC kombiniert
– prozedurale Schnittstelle
mit
– dynamischer SQL-Einbettung
Wichtige Interfaces des
JDBC-API
– Connection
• repräsentiert eine Verbindung zu einer Datenbank
– Statement
• Ermöglicht die Ausführung von SQL-Anweisungen
über eine gegebene Verbindung (Connection)
– ResultSet
• ermöglicht den Zugriff auf das Ergebnis einer mit
einem Statement ausgeführten SQL-Anfrage
Wichtige Interfaces des
JDBC-API
Connection
createStatement
Statement
Statement
executeQuery
ResultSet
ResultSet
JDBC-Treibertypen
Java-Anwendung
JDBC-Treibermanager
JDBC-ODBCBridge-Treiber
Native-APITreiber
ODBC-Treiber
ClientBibliothek
ClientBibliothek
Typ 1
JDBC-NetTreiber
NativeProtokollTreiber
Middleware
Typ 2
Typ 3
Typ 4
Ein JDBC-Treiber...
• Implementiert die Interfaces von java.sql, dem JDBC
API package, d.h. unter anderem auch Driver,
Connection, Statement und ResultSet
• Der Konstruktor der Klasse Driver trägt eine Instanz der
Klasse Driver durch Aufruf der Methode
DriverManager.registerDriver(new name.des.treibers)
in die in der Klasse DriverManager existierende Liste
der verfügbaren Driver Implementierungen ein
Eintragen der benötigten Driver Implementierung in
die Liste des DriverManager
•
Es gibt verschiedene Möglichkeiten den Konstruktor
einer Driver Implementierung auszuführen:
1.
Mit new eine neue Instanz der Klasse erzeugen
2.
Alle Driver Implementierungen die in der
Systemeigenschaft (Property) sql.drivers eingetragen
sind, werden vom DriverManager beim Start
automatisch geladen
3.
Durch einen Seiteneffekt der Methode
Class.forName(“Name des Treibers“)
Herstellen einer Verbindung über die
Klasse DriverManager
1.
2.
3.
Die Methode DriverManager.getConnection
bekommt eine URL als Parameter übergeben.
Der DriverManager versucht nacheinander mit den
Driver Implementierungen in der Liste eine
Verbindung zur Datenbank aufzubauen
Wenn ein zu der URL passender Treiber gefunden
und die Verbindung aufgebaut wurde, gibt
getConnection die Connection Implementierung
dieses Treibers an die Anwendung zurück
Beispiel: Eine JDBC-URL
Subprotokoll
Treiber-Art
Oracle Instanz
JDBC:ORACLE:THIN:@polaris:1521:ORCL
Netzadresse
Portnummer
Programmbeispiel: Herstellen einer
Verbindung über die Klasse
DriverManager Die Klasse Driver
dynamisch laden
Class.forName(“org.gjt.mm.mysql.Driver“)
String URL = “jdbc:mysql://localhost/test“;
String user = “sven“; passwd = “ibikom“;
Connection con = DriverManager.getConnection(url, user,
passwd);
Die zum Treiber gehörende
Implementierung des Interfaces
Connection anfordern
Probleme der Treiber-Verwaltung mit der
Klasse DriverManager
• Properties können nicht in jeder Situation
verwendet werden
• Wenn Class.forName(String treibername)
verwendet wird, bleibt es dem Programmierer
überlassen wo und wie der treibername gesetzt
wird
Falls später ein anderer Treiber verwendet
werden soll muss der Programm-Code evtl.
verändert werden!
Herstellen einer Verbindung über eine
Implementierung des DataSource interfaces
• Das DataSource Interface...
– ...repräsentiert eine Daten-Quelle und liefert Verbindungen mit
dieser.
– ...wird vom JDBC-Treiber implementiert
• Eine Implementierung dieses Interfaces besitzt eine Reihe
von Eigenschaften (Properties) welche die Datenquelle
identifizieren und beschreiben
• Ein DataSource Objekt kann in einem Naming Service
abgelegt und anschliessend vom Java-Programm über
einen Namen (über die JNDI-Implementierung des Naming
Service) angesprochen werden.
 bei einem Wechsel der DataSource ist keine Änderung
im Programm-Code notwendig!
Programmbeispiel:
Herstellen einer Verbindung über eine in
einem Naming Service abgelegte DataSource
Context ctx = new InitialContext();
In JNDI werden alle
Naming-Operationen
relativ zu einem Context
ausgeführt
DataSource ds =
(DataSource)ctx.lookup(“jdbc/RezeptDatenbank“);
Connection con = ds.getConnection(“user“,“pwd“);
Gibt eine Connection
Implementierung zurück
Gibt das Objekt zurück
das an den Namen
“jdbc/RezeptDatenbank“
gebunden ist
Wichtige Interfaces des
JDBC-API
Connection
createStatement
Statement
Statement
executeQuery
ResultSet
ResultSet
Programmbeispiel: Ein Statement Objekt erzeugen
und eine SQL-Anweisung an das DBMS übermitteln
mit der Connection
Implementierung ein
Statement erzeugen
Statement stmt = con.createStatement();
String query = “SELECT Name, Vorname FROM Person“;
ResultSet rs = stmt.executeQuery(query);
Über das ResultSet Objekt kann
anschliessend auf das Ergebnis der
Anfrage zugegriffen werden
SQL-Anweisung übermitteln
Wichtige Interfaces des
JDBC-API
Connection
createStatement
Statement
Statement
executeQuery
ResultSet
ResultSet
Der Zugriff auf die Daten im ResultSet
über einen Cursor
Spaltennamen
Nr
1
3
6
20
30
33
Name
Theke
Backe
Mussmal
Übel
Moll
Bolika
Vorname
Anna
Anna
Machbald
Ismir
Tesa
Anna
ResultSet
Cursor
Steuern des Cursors im ResultSet
• Verschiedene Methoden zur Steuerung der Position
des Cursors: next(), previous(), first(), last(), ...
• Der Cursor ist anfangs vor dem ersten Tupel
positioniert
Vor dem Lesen muss next() aufgerufen werden!
• next() liefert bei erfolgreicher Ausführung den Wert
true zurück
Abbildung zwischen Java- und JDBC-Typen
JDBC-Typ
Java-Typ
CHAR
String
VARCHAR
String
NUMERIC
java.math.BigDecimal
INTEGER
int
...
...
Programmbeispiel: Das Auslesen des
ResultSet
bereits
bekannt...
ResultSet rs = stmt.executeQuery(
“SELECT Nr, Name, Vorname from Person“);
INTEGER
While (rs.next()) {
int nr = rs.getInt(“Nr“);
VARCHAR
String Name = rs.getString(“Name“);
String Vorname = rs.getString(“Vorname“);
System.out.println(nr + “
}
“ + name + “
“ + vorname);
SQL-Statements die kein Ergebnis
liefern
• Neben SQL-Anfragen können auch
– Einfüge- (INSERT),
– Änderungs-(UPDATE),
Lösch-(DELETE) und
– DDL-Operationen(z.B. CREATE TABLE, DROP TABLE )
durchgeführt werden
• Für diese SQL-Operationen gibt es die Methode
executeUpdate, sie liefert als Ergebnis die Anzahl der
betroffenen Tupel der Relation
int rows = stmt.executeUpdate(
“UPDATE Person SET Name = ‘Dur‘ WHERE Vorname= ‘Moll‘“);
Transaktionssteuerung
• Es sind Kommandos zur Steuerung des
Transaktionsablaufes im Connection Interface definiert:
– void commit()
– void rollback()
• Nachdem eine Verbindung zur Datenbank hergestellt
wurde umfasst eine Transaktion jeweils nur eine
Anweisung, dieser Modus kann mit der Methode
setAutoCommit(false) ausgeschaltet werden
Erweiterungen des Statement
Interface
• Das PreparedStatement Interface erweitert
Statement
Statement
– Eine SQL-Anweisung kann mehrfach, mit
verschiedenen Werten als Parameter, ausgeführt
werden
PreparedStatement
• Das CallableStatement Interface erweitert
PreparedStatement
– Unterstützung von Stored Procedures
CallableStatement
Programmbeispiel: Anwenden eines
PreparedStatement
String insStr =
Platzhalter
“INSERT INTO Person VALUES (?,?,?)“;
PreparedStatement updStmt;
updStmt = con.prepareStatement (insStr);
updStmt.setInt(1,123); updStmt.setString(2,“Meier“);
updStmt.setString(3,“Hans“);
updStmt.executeUpdate();
Die Werte einsetzen
DBMS-unabhängige
Programmierung
• Escape Sequenzen
• DatabaseMetaData zum Abfragen der
Fähigkeiten eines DBMS
Escape Sequenzen
• In einem Statement enthaltene DBMSunabhängige Escape Sequenzen werden durch den
Treiber in die Syntax des DBMS übersetzt
• Escape Sequenzen gibt es z. B. für:
– Skalare Funktionen z. B. {fn
<function-name>
(argument list)}
– Outer joins z. B. {oj Table1 LEFT OUTER JOIN Table2 ON Nr=6}
– Stored procedures z. B. {call <procedure_name>
[(<arg-list>)]}
– Datumsangaben z. B. {d ´1997-07-24‘}
Informationen über das DBMS: Das
DatabaseMetaData Interface
• Über 150 Methoden, die Informationen über
die Datenbank und das DBMS liefern:
– Methoden die Informationen über die
Datenbank liefern
– Methoden, die die unterstützten Features
charakterisieren
– Methoden, die die Zulässigkeit von DDLAnweisungen als Teil von Transaktionen
spezifizieren
Was wurde nicht besprochen?
•
•
•
•
•
•
Einige ResultSet-Erweiterungen
Batch-Updates
SQL99-Datentypen
Connection Pooling
Verteilte Transaktionen
RowSets
Vorteile der Programmierung einer
Datenbankanwendung in Java
• Der Datenbank-Client ist durch Java
unabhängig von einer bestimmten
Zielplattform
• Die Anwendung ist (im Idealfall)
unabhängig vom
Datenbankmanagementsystem
Herunterladen