Ludwig Maximilians Universität München Institut für Informatik Lehr Lehr- und Forschungseinheit für Datenbanksysteme Skript zur Vorlesung Datenbanksysteme I Wintersemester 2011/2012 Kapitel p 11: Anwendungsentwicklung Vorlesung: Prof. Dr. Christian Böhm Übungen: Andreas Züfle, Züfle Sebastian Goebl Skript © 2004 Christian Böhm http://www.dbs.ifi.lmu.de/cms/Datenbanksysteme_I Client-Server-Architektur 2 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Datenbankanwendungen unterstützen gleichzeitige Arbeit von vielen Benutzern • Dienstnehmer (Client) nimmt Dienste eines Dienstleisters (S (Server) ) zur E Erfüllung füll seiner i Aufgaben A f b in i Anspruch: A h Client Server 1. Anforderung 2. Bearbeitung 3 Antwort 3. A t t Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Client-Server-Architektur • Für jeden Server bekannt, welche Dienste er erbringen kann • Protokoll: R l Interaktionen Regelt I ki (d.h. (d h Aufbau A fb der d Anforderung A f d undd der d Antwort) • Asymmetrische Beziehung zw. zw Client und Server – Möglich, daß ein Client seinerseits wieder Server für einen anderen Dienst ist: Client Server/Client Server 3 4 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D DB-Server • Datenbankanwendungen: – Mehrere Benutzer arbeiten auf gemeinsamen Daten – Zentrale Kontrollinstanz ist erforderlich – PCs sind Frontends zur Darstellung und benutzerfreundlichen Manipulation der Daten Clients Server Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Aufteilung g der Funktionalität • Funktionsgruppen von Datenbankanwendungen: – Präsentation und Benutzerinteraktion – Anwendungslogik (im eigentlichen Sinn) – Datenmanagement (Anfragebearbeitung) • Trennung an jeder beliebigen Stelle: – Präsentation und Interaktion meist vollst. im Client – Datenmanagement g meist vollständigg im Server – Anwendungslogik: • meist im Client • im Server: typ. Großrechner-Anwendungen • Aufteilung der Logik: „gespeicherte Prozeduren“ 5 6 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Benutzerschnittstelle Fat Client Stored Procedure Benutzerschnittstelle Benutzerschnittstelle Anwendungslogik Hauptprogramm Anwendungslogik DB Schnittstelle DB-Schnittstelle DB-Schnittstelle DB Prozeduren DB-Schnittstelle DB DB Serverr Thin Client Clientt Aufteilung g der Funktionalität Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Aufteilung g der Funktionalität • Trennung zwischen Client und Server auch innerhalb einer Funktionsgruppe möglich: – Web-Anwendung: S Server erbringt bi teilweise il i Präsentationsfunktionalität Pä i f k i li ä Client hat nur Standard-Darstellungsfunktionalität – Seiten-Server: Seiten Server: Teil der Anfragefunktionalität (SQL) liegt im Client Server hat nur die Funktionalität, Datenblöcke gem. Adresse zu speichern und zu laden • 3-stufige g Hierarchie: – Applikationslogik bildet eigenes Client-Server-Modell – Applikations-Server pp ist Datenbank-Client 7 Aufteilung g der Funktionalität DB-Schnittst. (SQL) Anwendungslogik Webserver A Anwendungslogik d l ik Seiten Schnittstelle Seiten-Schnittstelle DB-Schnittstelle DB DB Serverr Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D 8 Anwendungslogik DB-Schnittstelle DB Cliient Benutzerschnittstelle DB-Serverr Appl..-Serveer Benutzerschnittstelle Browser Application pp Server Page g Server Clientt Web Applikation pp Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Protokoll • Client und Server können – auf dem selben Rechner laufen – auf verschiedenen Rechnern laufen, die über ein Netzwerk miteinander kommunizieren • Die Kommunikation zwischen Client und Server wird in j d Fall jedem ll durch d h ein i Protokoll geregelt: l – Bei Web-Anwendungen: http – A.-Logik/DB-Schnittstelle: Spez. Protokoll des DBMS • Anforderung: im wesentlichen SQL-Anfrage • Antwort: Ant ort: Tabelle bzw. b Liste von on Tupeln T peln – Bei Applikationsservern: Standard-Protokolle Standard Protokolle wie RMI, RMI CORBA 9 10 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Vor-/Nachteile der Varianten • Kriterien: – Netzbelastung – Belastung des Server-Rechners (gemeinsame Ressource für alle) – Belastung der Clients-Rechner ( f schlecht (oft hl h ausgestattete Bürorechner) h ) – Flexibilität – Entwicklungsaufwand SQL Q Java Ausdrucksmächtigkeit Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Optimierbarkeit T i i Terminierung • SQL SQL: keine k i Schleifen, S hl if etc. t • Anwendungslogik: Konventionelle Programmiersprache nötig • SQL wird mit herkömmlicher Programmiersprache (Hostsprache) gekoppelt 11 Kopplung pp g SQL/Host-Sprache Q p 12 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Idee: – Java-Programm (z.B.) enthält SQL-Anfragen – Diese werden an DB-Server gesandt – Server schickt als Antwort Ergebnistabelle – Java-Programm verarbeitet diese Tabelle: • Darstellung der Tupel am Bildschirm • ggf. weitere Anforderungen an die DB • Probleme: – Wie können die SQL-Anfragen in das Programm i t i t werden integriert d (verschiedene ( hi d Sprachen) S h ) – Unterschiedliche Datenstruktur-Konzepte • Java J kkann nicht i ht Tabellen T b ll verarbeiten b it Integration g der Anfragen g Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Grundsätzlich zwei verschiedene Möglichkeiten: • Call-Level-Schnittstellen: Es gibt eine Bibliothek mit speziellen Prozeduren, die die A f Anfrage als l Parameter P enthalten: h l – CLI, ODBC, OCI, JDBC: Statement stmt = con con.createStatement createStatement () ; ResultSet rs = stmt.executeQuery (“select * from ...“) ; • Einbettungg (Embedded ( SQL): Q ) Ein spezielles Schlüsselwort oder Zeichen kennzeichnet SQL-Anfrage (Vorübersetzung): – Embedded SQL-C (und versch. andere), JSQL, SQLJ: #sql {insert into Mitarbeiter values (25, “Meier“, 1) } ; 13 Das Cursor-Konzept p • In beiden Fällen nicht möglich/sinnvoll, sofort die gesamte E b i T b ll an das Ergebnis-Tabelle d Hostprogramm H t zu übergeben: üb b – Nicht möglich wegen sog. Impedance Mismatch: 14 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • SQL beruht auf der Datenstruktur „Tabelle Tabelle“ • Java beruht auf der Datenstruktur „Datensatz“ (bzw. Tupel, Klasse) – Nicht i h sinnvoll, i ll weil il Ergebnis b i sehr h großß werden d kann: k • Client-Rechner oft schwach ausgestattet • Übertragung des gesamten Ergebnisses kostet Zeit Zeit, in der der Benutzer warten muß (erste Ergebnisse) • Anwendungsprogramm braucht oft nur einen Teil der Ergebnistupel Das Cursor-Konzept p • Deshalb wird die Ergebnistabelle grundsätzlich tupelweise an das Hostprogramm übergeben. • Cursor: Position des aktuellen Tupels Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D DB-Server: DB-Anwendung: Variablen: Anfrageergebnis: i: j: Cursor: 15 Programmierschritte g beim Cursor • Grundsätzlich sind 4 Schritte erforderlich: 16 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Declaration Verknüpfung des Cursors mit Q g einer bestimmten SQL-Anfrage O Open Auftrag an den DB-Server DB Server, die Anfrage zu bearbeiten Fetch Verarbeitung der Ergebnistupel durch das Anwendungsprogramm Close Freigabe von Ressourcen ((z.B. Ergebnistabelle g in der DB)) Weitere Aufgaben g Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Über das reine Absetzen von Anfragen hinaus sind weitere Interaktionen mit dem DBS nötig: – Verwalten der Verbindung: • Verbindungsaufbau zu einer oder mehreren DBs • Verbindungsabbau • Authentifizierung mit Benutzername/Passwort – Management von Transaktionen • commit • rollback – Fehlerbehandlungg – Aufruf von gespeicherten Prozeduren sowie deren Verwaltung 17 Java Database Connectivity y JDBC 18 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Call Level Interface (Bibliotheksfunktionen) • Eng verwandt mit Microsofts ODBC – ähnliches Konzept für verschiedene Wirtssprachen • Idee: Hersteller-Unabhängigkeit durch Treiber Applikation Treiber-Manager T ib 1 Treiber T ib 2 Treiber Oracle MySQL Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Verbindungsaufbau g • Der prinzipielle Ablauf einer DB-Anwendung umfasst die folgenden Einzelschritte: – Laden des geeigneten Treibers – Aufbau einer Verbindung zur Datenbank – Senden einer SQL-Anweisung – Verarbeiten der Anfrageergebnisse • Diesen Schritten sind jeweils Java-Klassen zugeordnet: – – – – java.sql.DriverManager java.sql.Connection java sql Statement java.sql.Statement java.sql.ResultSet 19 Treiber und Verbindungsaufbau g • Es muß also java.sql.* importiert werden. • Laden des Datenbank-Treibers für Oracle: Class.forName (“oracle.jdbc.driver.OracleDriver“) ; 20 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Einrichten Ei i h einer i Verbindung V bi d durch d h Treiber-Mgr: T ib M Connection con = DriverManager.getConnection ( “jdbc:oracle:oci8:@dbis01“ jdbc:oracle:oci8:@dbis01 , “scott“ scott , “tiger“) tiger ) ; richtet folgende Verbindung ein: – Datenbankname: dbis01 – Benutzername: scott – Passwort: tiger • Connection-Objekt (hier: con) ist Ausgangspunkt für alle weiteren Aktionen Änderungs-Anweisungen g g Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Ausgangspunkt: das Connection-Objekt • Zunächst muß ein Statement-Objekt erzeugt werden (dient für Verwaltungszwecke) • insert, delete und update mittels der Methode executeUpdate: Statement stmt = con.createStatement con createStatement () ; int rows = stmt.executeUpdate (“update Produkt set Bestand=5 where ProdID=3“) ; Transaktionssteuerung: • Nach Verbindungsherstellung Auto-Commit-Modus (jede Änderung wird ohne explizites Commit sofort permanent) • später Näheres 21 Retrieval-Anweisungen g • Ausgangspunkt: Wieder Connection-Objekt • Für Verwaltungszwecke: Statement-Objekt • Ein Cursor wird deklariert und geöffnet durch die Methode executeQuery (query): 22 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Statement stmt = con.createStatement () ; ResultSet rs = stmt.executeQueryy ((“select * from Mitarbeiter“)) ; • Das Rückgabeobjekt (hier rs) vom Typ ResultSet ist aber noch nicht die Ergebnistabelle selbst sondern eine ID für d entsprechenden den t h d Cursor C • Um 1. (2., 3,...) Datensatz zu laden, Methode next: while (rs (rs.next next ( ) ) { /* Datensatz verarbeiten */ } Schließen in JDBC implizit durch Garbage Collection ffalse, l wenn kein k i D Datensatz t t (mehr) vorhanden ist Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Retrieval-Anweisungen g • Zugriff auf die einzelnen Attribute durch Spalten-Indizes (beginnend bei 1) über die Funktionen: – getString (i) – ggetDouble (i) () – getInt (i) usw. die einen Wert des entsprechenden Typs liefern. • Beispiel: Statement stmt = con.createStatement ( ) ; ResultSet rs = stmt.executeQuery Q y (“select ( * from Mitarbeiter“)) ; while (rs.next ( ) ) { int pnr = rs.getInt (1) ; g name = rs.getString g g ((2)) ; String double gehalt = rs.getDouble (5) ; System.out.println (pnr + “ “ + name + “ “ + gehalt) ; } 23 Fehlerbehandlung g 24 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Datenbankanweisungen können fehlschlagen, z.B. – Connect mit einer nicht existenten Datenbank – Select auf eine nicht existente Tabelle usw. • In Java generell mit folgendem Konstrukt: try { // Aufruf von JDBC-Anweisungen, // die möglicherweise g Fehler generieren g } catch (SQLException exc) { // Fehlerbehandlung, z.B. System out println (exc.getMessage System.out.println (exc getMessage ( ) ) ; } Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D Vorübersetzte SQL-Anfragen Q g • Bisher: Jede Anfrage wird als String an DBMS übergeben – Vorteil: Flexibel – Nachteil: N h il Jedes J d mall Übersetzungsaufwand Üb f d • Werden oft ähnliche Anfragen gestellt, empfiehlt sich, auf wiederholte Übersetzung zu verzichten – Parametrisierbarkeit ist wichtig PreparedStatement P dSt t t stmt t t = con.prepareStatement St t t ( “ insert into Mitarbeiter values (?, ?, ?, NULL, 0.0) “ ); • Die einzelnen Platzhalter müssen vor dem Ausführen mit SetInt, SetString, ... besetzt werden – Spaltenindizes p (beginnend ( g bei 1)) 25 Vorübersetzte SQL-Anfragen Q g 26 Kapitel 11: An K nwendungseentwicklung Datenbanksysteme I D • Beispiel: PreparedStatement stmt = con.prepareStatement ( “ insert into Mitarbeiter values (?, ( ?, ?, NULL, 0.0)) “ )); // erstes Insert: stmt.setInt (1, 25) ; stmt.SetString (2, “Wagner“) ; stmt.SetString (3, “Richard“) ; stmt.executeUpdate ( ) ; // zweites Insert: stmt.SetInt t t S tI t (1, (1 26) ; ... stmt.executeUpdate ( ) ;