Grundlagen zur Verwendung und Entwicklung von Datenbanksystemen Vorlesung im Wintersemester 2007/08 (Aspekte der Anbindung von Datenbanken) WS07/08 – DBS Part 5 Prof. Dr. Andreas Schmietendorf 1 Inhalte des Abschnitts § Grundlegende Aspekte § ODBC-Schnittstelle § JDBC-Schnittstelle § Beispiel einer JDBC-Implementierung § Gespeicherte Prozeduren (Stored Procedures) WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 2 Aspekte zur Anbindung von Datenbanken WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 3 Client-Server Architektur Benutzerschnittstelle Anwendungslogik Benutzerschnittstelle Client DB-Schnittstelle Middleware Anwendungslogik DB-Schnittstelle DBMS-Protokoll Daten ApplikationsServer DBMS-Protokoll DB-Server 2-Schichten-Architektur Client Daten DB-Server 3-Schichten-Architektur Quelle: Heuer, A.; Saake, G.; Sattler, K.-U.; Datenbanken kompakt, mitp-Verlag, 2003 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 4 Cursor-Konzept WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 5 Cursor-Konzept § Unterschiedliche Datenstrukturkonzepte - Java – Object als Basiskonstruktur (vgl. Aufnahme eines Tupels) - SQL – Konzept der Relation (Menge von Tupeln) § Ausgleich des „Impedance Mismatch“ durch - Verwendung verketteter Listen – Traversieren durch die Listen - Cursor-Konzept à abstrakte Sichtweise auf eine Relation à Cursor als Iterator über einer Liste von Tupeln, wobei dieser Zeiger je nach Implementierung vor- und zurückgesetzt werden kann WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 6 Konzepte zur Datenbankanbindung § Einbettung von SQL in Programmiersprachen (Embedded SQL) - Statische Einbettung (SQL-Anweisungen sind vordefiniert und werden durch einen Precompiler analysiert und übersetzt) - Dynamische Einbettung (SQL-Anweisungen können zur Laufzeit zusammengesetzt werden) § Call-Level-Schnittstellen - Herstellerspezifische Implementierungen (z.B. Oracle OCI, DB2 CLI) - SQL/CLI der X/Open-Group als ISO-Standard (Quelltextkompatibel) - Microsoft ODBC bzw. Java JDBC WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 7 ODBC-Schnittstelle WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 8 ODBC-Schnittstelle Zugriff auf verschiedene Datenquellen mittels ODBC § ODBC - Open Database Connectivity - durch Microsoft initiierter offener Standard à SQL/CLI - Entkopplung der Anwendung von Datenbank-Details - API für die Programmiersprache C - Verwendung lokaler und entfernter Datenbanken - Wechsel der Datenbank erfordert keine Neukompilierung - Verfügbar für Windows- und UNIX-Systeme § Seit Windows 2000 ist ODBC als Bestandteil des Betriebssystems WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 9 ODBC-Schnittstelle Applikation ODBC API Treibermanager ODBC API Treiber Treiber Daten Daten Quelle: Heuer, A.; Saake, G.; Sattler, K.-U.; Datenbanken kompakt, mitp-Verlag, 2003 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 10 ODBC-Architektur § Verwendung einer 4-Schichten-Architektur - ODBC-Applikation (ODBC-Bibliothek im Programmcode) - ODBC-Driver Manager – verwaltet Datenquellen und entkoppelt die Anwendungen von den systemspezifischen DB-treibern - ODBC-Treiber – regelt Abwicklung der Datenzugriffe - Datenquelle liefert die entsprechende Daten § Verwendung so genannter Datenquellen à eigener Name - Vorkonfiguriert vom Administrator à Windows Systemsteuerung - Angabe der benötigten Verbindungsinformation - Servername, Netzwerkadresse, WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 11 Verwendung der ODBC-Schnittstelle § Struktur zur Verwendung der ODBC-Schnittstelle - Aufbau einer Verbindung zur Datenbank - Ausführen einer entsprechenden SQL-Anweisung - Verarbeitung der Ergebnismenge - Beenden der Verbindung zur Datenbank § Microsoft Foundation Classes (MFC) – C++ Klassenbibliothek - Bereitgestellte Klassen zur Nutzung der ODBC-Funktionen • Klasse CDatabase – Verbindung zur Datenbank • Klasse CRecordset – Anfragebearbeitung • CRecordset-Objekt – Navigieren durch die Antwortmenge WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 12 Beispiel einer Implementierung void print_emps() { // Datenbank oeffnen CDatabase db; db.Open("DSN=SybaseSQLServer",FALSE,TRUE,\"ODBC;UID=quix"); // RecordSet initialisieren EmployeeRecordSet rs(&db); rs.Open(CRecordset::snapshot, "Select Name,Salary from Employee where Salary > 100000"); // Ergebnis ausgeben rs.MoveFirst(); while(!rs.IsEOF()) { rs.DoFieldExchange(); cout << rs.name << " verdient " rs.salary << " DM.\n"; rs.MoveNext(); } } Quelle: Quix, C.: Der ODBC-Standard, http://www-i5.informatik.rwth-aachen.de/~quix/da/node9.html WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 13 JDBC-Schnittstelle WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 14 Datenbankanbindung mit JDBC § JDBC - Java Database Connectivity API zur Programmierung von Datenbankverbindungen (Konzeptionell angelehnt an ODBC) § JDBC nutzt für den Datenbankzugriff das durch die X/Open standardisierte Call-Level-Interfaces (CLI) - Low level API, kein direktes objektorientiertes Mapping - Implementierungen von Oracle, Sybase, Informix, DB/2, IMS,... § Aufgaben des JDBC-Interface - Verbindungsaufbau zur Datenbank - SQL Kommandos (vgl. SELECT name FROM MITARBEITER) - Ergebnisse verarbeiten und in der Oberfläche anzeigen WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 15 Datenbankanbindung mit JDBC § Das JDBC-Interface bietet verschiedene Treibertypen (Typ 1 bis 4) - Entscheidung über die Schichten der Applikation - Vorteile einer mehrschichtigen C/S-Architektur berücksichtigen § Verwendbare Systeme (ohne Firewall): - Web-Server: MS Internet Information Server - JDBC-Applikations-Server (z.B. Weblogic „Tengah“ www.weblogic.com) - MS SQL-Server WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 16 Datenbankanbindung mit JDBC Ethernet Client Web-Browser Server HTTP-Anfrage Web-Server (z.B. MS IIS) (z.B. Netscape) html-Dateien class-Dateien DB-Anfrage JDBC-Server Java-Applet (z.B. IDS-Server) Datensätze Client DB-Server Daten Server WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 17 Datenbankanbindung mit JDBC § Type 1 Treiber: JDBC-ODBC Bridge - keine Hardwareunabhängigkeit bei Applet-Anwendungen - DB-Zugriffe erfolgen via dem ODBC-Treiber - Zu fast jedem DB-System sind ODBC-Treiber verfügbar § Type 2 Treiber: Native partly Java Driver - Treiber des entsprechenden DBMS Herstellers werden benötigt - Wandlung der JDBC-Aufrufe in herstellerspezifische Client-API für das jeweilige Datenbank-System Merke: Treibertypen 1 und 2 sind für Applet-Anwendungen ungeeignet. WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 18 Datenbankanbindung mit JDBC § Type 3 Treiber: Java Net all Java-Driver - Treiber nur zum Teil in Java geschrieben (eigentlich Proxy beim Client) Middleware zwischen Java-Client und DB-Server notwendig keine spezielle Software beim Client (Applets möglich) notwendig mehrstufige C/S-Architekturen sind realisierbar (n-Tier) § Type 4 Treiber: - Treiber komplett in 100% Java geschrieben - Treiber wird bei Start des Browsers übertragen (rel. groß) - Mehrstufige C/S-Architekturen werden unterstützt Schlußfolgerung: Treibertyp 4 ist für mehrstufige C/S-Architekturen die optimale Lösung (z.B. Einsatz im Kontext eines Web-Serves) WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 19 Datenbankanbindung mit JDBC SQL-2 Entry Level Standard von 1992 § Problem der Portierung einer Anwendung auf ein anderes Datenbanksystem (Problem der verschiedenen SQL-Dialekte) § Forderung von SUN an die JDBC-Hersteller zur Sicherung eines minimalen Anspruches auf Standardisierung § SUN stellt eine entsprechende Test-Suite zum Nachweis der Konformität von JDBC-Treibern bereit § Kritisch ist die Verwendung von Funktionen die über den o.g. Standard hinausgehen WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 20 Datenbankanbindung mit JDBC Meistgenutzte Klassen des JDBC-API (import java.sql.*) - java.sql.DriverManager Verwalten der Datenbankverbindung - java.sql.DriverConnection Verbindungsaufbau zur Datenbank - java.sql.Statement beinhaltet den auszuführenden SQL-Befehl wird als ASCI-Zeichenkette übergeben - java.sql.ResultSet Zugriff auf die Ergebnismenge des ausgeführten SQL-Befehls WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 21 Datenbankanbindung mit JDBC Öffnen einer Verbindung § DB-Zugriff erfordert die Etablierung einer Verbindung zur DB § Schritte beim Verbindungsaufbau - Datenbanktreiber laden - Initialisierung des Datenbanktreibers - Erzeugen eines Verbindungsobjektes § Verbindungsobjekt - Bleibt während der gesamten Verbindung bestehen - Lieferant für spezielle Objekte zur Abfrage & Veränderung der DB WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 22 Datenbankanbindung mit JDBC Ausprägungen von getConnection (Verbindungsaufbau zur Datenbank) § static Connection getConnection( string url ) § static Connection getConnection( string url, String user, String password ) § static Connection getConnection( string url, Properties info ) WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 23 Datenbankanbindung mit JDBC Aufbau des Connection-Strings: § Besteht aus mehreren Teilen § Durch Doppelpunkt voneinander getrennt § 1. Teil: immer jdbc § 2. Teil: Sub-Protokoll – Angabe des konkreten Treibers § Weitere Teile: Treiberspezifisch § Beispiele: Firebird-DB con = DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:DirDB","sysdba","masterkey"); MySQL-DB con = DriverManager.getConnection("jdbc:mysql://localhost/hs_mitarbeiter", "root", ""); WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 24 Datenbankanbindung mit JDBC Erzeugen von Anweisungsobjekten § Abfragen und Änderungen erfolgen mittels Anweisungsobjekten § Implementieren das Interface Statement bzw. entspr. Subinterfaces § Einfachste Form „createStatement“ mit folgenden Methoden - executeQuery (String sql) - executeUpdate (String sql) § Erzeugung unparametrisierter Abfragen und Änderungen der DB § Rückgabe: - Einfacher numerischer Ergebniswert (Erfolg bzw. Misserfolg) - Menge von Datenbanksätzen, als Ergebnis der Abfrage WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 25 Datenbankanbindung mit JDBC Statement-Objekte: § Häufig kostenintensive Ressourcen - Belegung von Speicherplatz - Belegung von Rechenzeit § Erzeugung einer großen Anzahl sollte vermieden werden § Besserer Stil: - Anlegen einer Reihe vordefinierter Statement-Objekte - Mehrfache Verwendung von Statement-Objekten - Allerdings besteht die Gefahr undefinierter Zustände WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 26 Datenbankanbindung mit JDBC Datenbankabfragen – Verwendung der executeQuery-Methode: public ResultSet executeQuery (String sql) throws SQLException § Die oben dargestellte Methode erwartet eine für die Datenbank gültige SELECT-Anweisung (z.B. SELECT * FROM kunden WHERE name = ‘Meier‘) und gibt einen ResultSet zurück. Das ResultSet repräsentiert die Ergebnismenge. § Schrittweisen durchlaufen des ResultSet mittels der Methode next. boolean next() WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 27 Datenbankanbindung mit JDBC Datenbankabfragen – Verwendung der executeQuery-Methode: § Zugriff auf die Spalten des durch next referenzierten Tupels - getXXX (int n), Übergabe eines numerischen Wertes - getXXX (String x), Übergabe eines Spaltennamens § Ausgewählte Get-Methoden von ResultSet - getBoolean - getByte - getDate - getString - getInt WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 28 Datenbankanbindung mit JDBC Datenbankänderungen – Verwendung der executeUpdate-Methode: public int executeUpdate (String sql) throws SQLException § Die oben dargestellte Methode erwartet eine für die Datenbank gültige INSERT, UPDATE oder DELETE-Anweisung (z.B. INSERT INTO kunden VALUES (122, ‘Meier‘, ‘Andreas‘, 13509, ‘Berlin‘, ‘Wittestrasse 30H‘) bzw. eine DDL-Anweisung zum Ändern der Datenbankstruktur. § Diese Methode gibt keine Ergebnismenge zurück! § Bei Erfolg wird 1 zurückgegeben, andernfalls eines SQLException WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 29 Datenbankanbindung mit JDBC Klasse SQLException (Ausnahmebehandlung): § Verbindungsaufbau zur Datenbank ist fehlgeschlagen § Probleme mit SQL-Anweisungen - Syntaxfehler - Semantische Fehler – z.B. falsche Typisierung § Behandlung einer SQLException catch (SQLException sqle) while (sqle != null) { System.err.println(sqle.toString()); System.err.println(“SQL-Status: “ + sqle.getSQLState()); System.err.println(“ErrorCode: “ + sqle.getSQLState()); } } WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 30 Beispiel für die Verwendung des JDBC-Interfaces WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 31 JDBC-Beispiel Benötigte Software bzw. Systeme: § Laufende Firebird-Datenbank (z.B. mittels IBO-Console bearbeiten) § http://sourceforge.net/projects/firebird “firebird-jca-jdbc-driver” § firebirdsql-full.jar – enthält alle benötigten Klassen § - firebirdsql.jar - mini-concurrent.jar - jaas.jar (Innerhalb des JDK 1.4) - mini-j2ee.jar (JDBC classes) - log4j-core.jar (Logging-Funktionalitäten) JDK 1.4.x - Setzen der Java-Umgebungsvariablen - Unter WinXP: Start – Einstellungen – Systemsteuerung – System - Erweitert - CLASSPATH à .;C:\j2sdk1.4.2_08\lib\firebirdsql-full.jar - JAVA_HOME à C:\j2sdk1.4.2_08 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 32 JDBC-Beispiel § Firebank-Datenbank mittels DDL aufsetzen § Java-Programm implementieren - Treiber laden Class.forName("org.firebirdsql.jdbc.FBDriver"); - Variable für Connection-Objekt: private Connection con; - Datenbankverbindung (Treiber:Server:Datenbank) herstellen mit: § DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:C:/Pro gramme/Firebird/examples/employee.gdb","sysdba","masterkey"); - Treiber: jdbc:firebirdsql - Server: localhost/3050 - Datenbank: C:/Programme/Firebird/examples/employee.gdb - Nutzername/Passwort: sysdba/masterkey WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 33 JDBC-Beispiel WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 34 JDBC-Beispiel import java.sql.*; public class JDBCTest { // A. Schmietendorf – Fachhochschule für Wirtschaft Berlin – WS07/08 // JDBC-Testbeispiel im Rahmen der Vorlesung Programmierung DBS-Systeme private Connection con; private java.sql.Statement stm; public static void main(String argv[]) { new JDBCTest().access(); } WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 35 JDBC-Beispiel public void access() { try { Class.forName("org.firebirdsql.jdbc.FBDriver"); } catch(ClassNotFoundException ex) { System.out.println("Class.forName : " + ex.getMessage()); } try { con = DriverManager.getConnection("jdbc:firebirdsql:localhost/3050:C:/Programme/Firebird/ examples/employee.gdb","sysdba","masterkey"); stm = con.createStatement(); stm.executeUpdate("INSERT INTO country VALUES ('Bulgaria','Leva')"); System.out.println("Daten erfolgreich in die Datenbank eingetragen"); WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 36 JDBC-Beispiel System.out.println("Daten aus der Datenbanktabelle auslesen"); ResultSet rs = stm.executeQuery ("SELECT * FROM country"); while (rs.next ()) { String country = rs.getString (1); String currency = rs.getString (2); System.out.println(country + " " + currency); } System.out.println("Ende der Datenausgabe - A. Schmietendorf"); // Ressourcenffreigabe rs.close(); con.close(); } catch (SQLException ex) { System.out.println(ex.getMessage()); } } } WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 37 JDBC-Beispiel § Verwendung eines ResultSet-Objektes zur Ergebnisverwaltung der Anfrage § Navigation über die Ergebnismenge erfolgt nach dem Cursor-Prinzip § Weitersetzen des Cursors mit der Methode next § Zeilenauswahl entspricht der aktuellen Position des Cursors § Spaltenauswahl der aktuellen Tupel mit getXXX-Methode und Spaltenindex ResultSet rs = stm.executeQuery ("SELECT * FROM country"); while (rs.next ()) { String country = rs.getString (1); String currency = rs.getString (2); System.out.println(country + " " + currency); } WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 38 JDBC-Beispiel WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 39 Gespeicherte Prozeduren WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 40 Embedded SQL für Java § Standard zur Kopplung von Java mit SQL § Bestandteile der SQLJ-Spezifikation - Embedded SQL für Java (Part 0) - Java Stored Procedures (Part 1) - Klassen für benutzerdefinierte SQL-Datentypen (Part 2) § Verwendung eines Precompilers à SQLJ-Translator - Übersetzt die in „echten“ Java-Code (Basis: *.sqlj) - Syntax und Semantik-Prüfung der eingebetteten SQL-Anweisungen WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 41 Gespeicherte Prozeduren § Erweiterung von SQL um Programmiersprachkonstrukte - Sequenz - Bedingte Ausführung - Schleifen (Iteration) - Prozeduren & Funktionen § Verwaltung von „Stored Procedures“ auf der Datenbankseite - Genutzt auf der Seite des Datenbanksystems - Impliziert den lokalen Zugriff auf die Daten § Beispiele für entsprechende Implementierungen - Oracle PL/SQL - Microsoft Transact-SQL à SQL-Standard – Ansatz zur SQL-Spracherweiterung SQL/PSM WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 42 Gespeicherte Prozeduren § Vorteile - Möglichkeit zur Minimierung des Netzwerkverkehrs - Optimierungen können sich auf mehrere Anweisungen beziehen - Kontrolle von Funktionalität im DBMS - Hilfsmittel zur Strukturierung großer Anwendungen - Reduktion funktionsbedingter Redundanzen - Rechtevergabe auf Prozedurebene - Verwendung zur Integritätssicherung – z.B. Aktionsteil eines Triggers § Nachteile - Komplizierte Fehlersuche - Häufig mit herstellerabhängigen Elementen versehen WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 43 SQL/PSM § PSM – Persistent Stored Modules (erste Version 1996, SQL3, SQL99 § Beispiele für behandelte Aspekte: - Module beinhalten gespeicherte Prozeduren bzw. Funktionen • create module • drop module - Syntaktische Festlegungen einer call-Anweisung • Parameter • Ausnahmebehandlung - Syntaktische Konstrukte für z.B. Schleifen - Verwendung existierender Programmiersprachen à Alle großen DBMS-Hersteller unterstützen gespeicherte Prozeduren, zumeist allerdings nicht PSM-konform WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 44 Gespeicherte Prozeduren in Java Implementierung und Aufruf: § Implementierung der Routine - Möglichkeit zur Minimierung des Netzwerkverkehrs - Optimierungen können sich auf mehrere Anweisungen beziehen § Installation im DBMS-Server - Übertragen des übersetzen Codes zum Server - Verfügbarkeit gewährleisten § Registrierung - Bekanntmachen der Routine - z.B. durch create procedure bzw. durch create function § Aufruf - Aus einer Client-Anwendung heraus - Im Rahmen einer SQL-Anweisung Quelle: Heuer, A.; Saake, G.; Sattler, K.-U.; Datenbanken kompakt, mitp-Verlag, 2003 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 45 Datenbankzugriff mit JDBC Quelle: Heuer, A.; Saake, G.; Sattler, K.-U.; Datenbanken kompakt, mitp-Verlag, 2003 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 46 Datenbankzugriff mit SQLJ § Prozeduren sind als Klassenmethoden (static) zu implementieren § Verbindung zur Datenbank ist implizit vorhanden § #SQL – Schlüsselwort für SQL-Anweisungen unter Java Quelle: Heuer, A.; Saake, G.; Sattler, K.-U.; Datenbanken kompakt, mitp-Verlag, 2003 WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 47 Installation & Registrierung § Installation - Kompilierung mit einem klassischen Java-Compiler - Bei SQL unter Nutzung eines SQLJ-Translators - Erzeugen eines jar-Archives - Kopieren des jar-Archivs zum Datenbankserver § Registrierung - SQL-Name, SQL-Typen der Parameter - Zuordnung zu den korrespondierenden Java-Methoden - Verwendung der Anweisung create procedure WS07/08 – DBS Part 6 Prof. Dr. Andreas Schmietendorf 48