500 likes | 590 Views
Programmierung von Client/Server-Anwendungen Verwendung von API‘s (JDBC). Übersicht zur Vorlesung. Persistenzsicherung von Java-Objekten Datenbankanbindung mit Hilfe von JDBC Beispiel zur Verwendung des JDBC-Interfaces Verwendung von Prepared Statements
E N D
Programmierung von Client/Server-AnwendungenVerwendung von API‘s (JDBC) Prof. Dr. Andreas Schmietendorf
Übersicht zur Vorlesung • Persistenzsicherung von Java-Objekten • Datenbankanbindung mit Hilfe von JDBC • Beispiel zur Verwendung des JDBC-Interfaces • Verwendung von Prepared Statements • Weiterführende Themenstellungen zum JDBC-Interface Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung von Java-Objekten Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung • Objektserialisierung – Objekt als Datenstrom wegschreiben • Manuelles OR-Mapping • Verwendung des JDBC-Frameworks • Embedded SQL (sehr verbreitet in C bzw. C++, bei Java aber keine Bedeutung) • Nutzung objektorientierter Datenbanksysteme • Verwendung des DAO-Entwurfsmusters (Datenabstraktion) • Einsatz von EJB‘s (Entity Beans) • OR-Mapping Tools (z.B. Hibernate) Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung Hibernate-Anwendungen bestehen klassisch aus 4 Teilen: 1. Hibernate-Konfigurationsdatei (XML) 2. Pro persistenter Klasse eine Hibernate Mapping XML-Datei 3. Der Hibernate Java Library (JAR-Datei) 4. HQL (Hibernate Query Language) OO-Erweiterung zu SQL sowie: 1. Den Java-Klassen 2. Der Datenbank mit dem Datenbank Schema Prof. Dr. Andreas Schmietendorf
Möglichkeiten zur Persistenzsicherung OR-Mapping Tools: http://www.service-architecture.com/products/object-relational_mapping.html Prof. Dr. Andreas Schmietendorf
Datenbankanbindung mit Hilfe von JDBC Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
Datenbankanbindung mit JDBC Prof. Dr. Andreas Schmietendorf
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. Prof. Dr. Andreas Schmietendorf
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) Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
Datenbankanbindung mit JDBC Öffnen einer Verbindung • Bevor auf die DB zugegriffen werden bedarf es einer Verbindung • 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 Prof. Dr. Andreas Schmietendorf
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 ) Prof. Dr. Andreas Schmietendorf
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", ""); Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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() Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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()); } } Prof. Dr. Andreas Schmietendorf
Beispiel für die Verwendung des JDBC-Interfaces Prof. Dr. Andreas Schmietendorf
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 Prof. Dr. Andreas Schmietendorf
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:/Programme/Firebird/examples/employee.gdb","sysdba","masterkey"); • Treiber: jdbc:firebirdsql • Server: localhost/3050 • Datenbank: C:/Programme/Firebird/examples/employee.gdb • Nutzername/Passwort: sysdba/masterkey Prof. Dr. Andreas Schmietendorf
JDBC-Beispiel Prof. Dr. Andreas Schmietendorf
JDBC-Beispiel import java.sql.*; public class JDBCTest { // A. Schmietendorf – Fachhochschule für Wirtschaft Berlin – WS06/07 // JDBC-Testbeispiel im Rahmen der Vorlesung Programmierung C/S-Systeme private Connection con; private java.sql.Statement stm; public static void main(String argv[]) { new JDBCTest().access(); } Prof. Dr. Andreas Schmietendorf
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"); Prof. Dr. Andreas Schmietendorf
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()); } } } Prof. Dr. Andreas Schmietendorf
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); } Prof. Dr. Andreas Schmietendorf
JDBC-Beispiel Prof. Dr. Andreas Schmietendorf
Verwendung von Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements • Prepared Statements sind parametrisierte SQL-Anweisungen • Werden deklariert und zum Vorkompilieren der DB übergeben • Können später beliebig of ausgeführt werden • Vorteile: • Vorbereitungssarbeiten werden nur einmal erledigt • Syntaxanalyse • Vorbereitung der Abfragestrategie und -optimierung • Bessere Performance • JDBC Prepared Statements im Interface PreparedStatement Prof. Dr. Andreas Schmietendorf
Prepared Statements • Methode preparedStatement: PreparedStatement pst = con.preparedStatement ( “SELECT * FROM ?“ ); • Parametrisierung von executeQuery bzw. executeUpdate • Aufruf einer entsprechenden set-Methode je Fragezeichen • Ausführung mittels executeQuery bzw. executeUpdate Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements public class DBClient { public static void main(String[] args) throws Exception { DBConnect MyDBConnect = new DBConnect(); // Suche ueber den Namen String res1 = MyDBConnect.searchForName("Mueller"); System.out.print(res1); // Suche ueber die email-Adresse String res2 = MyDBConnect.searchForEMail("schmidt@gmx.de"); System.out.print(res2); // Suche ueber die Raumnummer String res3 = MyDBConnect.searchForRaum("113"); System.out.print(res3); } } Prof. Dr. Andreas Schmietendorf
Prepared Statements public class DBClient { public static void main(String[] args) throws Exception { DBConnect MyDBConnect = new DBConnect(); // Suche ueber den Namen String res1 = MyDBConnect.searchForName("Mueller"); System.out.print(res1); // Suche ueber die email-Adresse String res2 = MyDBConnect.searchForEMail("schmidt@gmx.de"); System.out.print(res2); // Suche ueber die Raumnummer String res3 = MyDBConnect.searchForRaum("113"); System.out.print(res3); } } Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Prepared Statements Prof. Dr. Andreas Schmietendorf
Weiterführende Themenstellungen zum JDBC-Interface Prof. Dr. Andreas Schmietendorf
Transaktionssicherung • Steuerung des Transaktionsverhalten der Datenbank über 3 Methoden des Connection-Objektes • void commit() • void rollback() • void setAutoCommit (boolean autoCommit) • Nach dem Aufbau einer JDBC-Verbindung • DB im Auto-Commit-Modus (Vorgabe JDBC) • Jede einzelne Anweisung gilt als separate TA • Änderung mittes setAutoCommit (false) • TA müssen explizit durch Aufruf von commit bestätigt werden • Mittels rollback kann eine TA zurückgesetzt werden Prof. Dr. Andreas Schmietendorf
Transaktionssicherung Transaction Isolation Level (Beeinflussung des Sperrverhalten) • Steuerung des Grades der Parallelität • Hoher Transaction Level • desto weniger Konsistenzprobleme • geringerer Durchsatz, d.h. Performanceprobleme • Niedriger Tranaction Level • ggf. potentielle Konsistenzprobleme • besseres Performanceverhalten Prof. Dr. Andreas Schmietendorf
Transaktionssicherung • Verfügbare Transaction Isolation Level • Connection.TRANSACTION_NONE • Connection.TRANSACTION_READ_UNCOMMITTED • Connection.TRANSACTION_READ_COMMITTED • Connection.TRANSACTION_REPEATABLE_READ • Connection.TRANSACTION_SERIALIZABLE • Lesen und Ändern des Transaction Isolation Level • int getTransactionIsolation ( ) • void setTransactionIsolation ( ) Prof. Dr. Andreas Schmietendorf