Persistenz 1: Datenbanken Modellierung: ERM und Relationales Schema Schema-Implementierung: DDL und XML SQL, ODBC und JDBC Objekt-relationales Mapping (ORM) Was ist Persistenz? Persistenz bedeutet ursprünglich, dass Objekte die Programmausführung "überleben" durch Auslagerung auf externe Speichermedien, z.B. durch Serialisierung und Dateiausschrieb bei Shutdown Für langlaufende Programme: Zwischenauslagerung nicht benötigter Objekte "Hibernation" (Winterschlaf) Persistenz heute: Dynamische Ein- und Auslagerung von Objekten (Materialisierung und Dematerialisierung) normalerweise in Datenbanken (c) schmiedecke 10 SE2-5-DB 2 Datenbank-Modellierung Datenbanken verwalten Entitäten und ihre Beziehungen Datenmodelle auf verschiedenen Abstraktionsstufen ERM – Entity-Relationship-Modell – ähnlich dem UML-Klassendiagramm aber ohne Vererbung – unabhängig vom Datenmodell (m:n-Beziehungen sind möglich) – kanonische Abbildung auf das Relationale Modell (Verknüpfungstabellen) – Notationsfalle: Kardinalitäten werden an der Quelle notiert (UML am Ziel) (c) schmiedecke 10 SE2-5-DB 3 ERM-Beispiel (UML-Notation) class ERM online shop Produk t - Orde r Produktnummer: int Preis: double Name: String * Info: String AnzKolli: int Gewicht: double * - Bestelldatum: Date Lieferdatum: Date Versandform: String Rechnungsnummer: int Bearbeiter: String * * * 1 * 1 Kunde Einkaufsw agen - Datum: Date (c) schmiedecke 10 Kreditk arte 1 1 - Name: String Strasse: String 1 Ort: String PLZ: int SE2-5-DB 1.. * - Kartentyp: String Kartennummer: int Gültigkeit: Date 4 Das Relationale Datenmodell Das Relationale Modell – – – – Entitäten als Tupel in Relationen (Zeilen in Tabellen) Tupel (Zeilen) eindeutig identifizierbar durch Primärschlüssel alle Attribute (Spalten) skalar (1.NF) Beziehungen als Verweise in andere Relationen (Fremdschlüssel) Integritätsbedingungen – Entitätsintegrität: Primärschlüssel sind eindeutig – Referentielle Integrität: Zu jedem Fremdschlüssel existiert ein Ziel. Relationale Datenbank-Managementsysteme – extrem effiziente und zuverlässige Implementierungen (c) schmiedecke 10 SE2-5-DB 5 ERM Relationales Modell Jedes Tupel benötigt einen Primärschlüssel – inhärenter Schlüssel: eindeutiges Attribute oder eindeutige Attributgruppe – Surrogatschlüssel: hinzugefügter eindeutiger Wert ohne eigene Semantik, zumeist ein Zahlenwert In der Softwareentwicklung benutzen wir immer Surrogatschlüssel – durch inhaltliche Anpassungen der Daten kann sonst die Eindeutigkeit nachträglich verloren gehen. (c) schmiedecke 10 SE2-5-DB 6 ERM Relationales Modell Einfache Entitätstypen werden direkt auf Tabellen abgebildet: Einfach ist ein Entitätstyp dann, wenn alle Attributte skalar sind, d.h. Zahlen, Datumswerte oder kurze Texte (c) schmiedecke 10 SE2-5-DB 7 ERM Relationales Modell Strukturierte Attribute werden in skalare Komponenten zerlegt – wenige Attribute werden zu mehreren Spalten der Ursprungstabelle – variabel viele oder viele Attribute werden zu einer eigenen Tabelle (c) schmiedecke 10 SE2-5-DB 8 ERM Relationales Modell Listentypen werden (möglichst) auf eine Tabelle mit rückweisender Beziehung abgebildet (c) schmiedecke 10 SE2-5-DB 9 ERM Relationales Modell 1:1-Beziehungen werden als Fremdschlüssel dargestellt – bideriektional: gegenseitige Fremdschlüssel (c) schmiedecke 10 SE2-5-DB 10 ERM Relationales Modell Eine unidirektionale m:1-Beziehung wird als Fremdschlüssel dargestellt (c) schmiedecke 10 SE2-5-DB 11 ERM Relationales Modell 1:m-Beziehungen, m:n-Beziehungen und bidirektionale m:1-Beziehungen werden mithilfe einer Verknüpfungstabelle dargestellt. – Die Verknüpfungstabelle benötigt keinen eigenen Primärschlüssel – ein eigener Primärschlüssel ermöglicht die Abbildung assoziativer Klassen (im ORM) (c) schmiedecke 10 SE2-5-DB 12 Relationales Schema class ERM online shop Produk t - Orde r Produktnummer: int Preis: double Name: String * Info: String AnzKolli: int Gewicht: double * - Bestelldatum: Date Lieferdatum: Date Versandform: String Rechnungsnummer: int Bearbeiter: String * * * 1 * 1 Kunde Einkaufsw agen - Datum: Date (c) schmiedecke 10 Kreditk arte 1 1 - Name: String Strasse: String 1 Ort: String PLZ: int SE2-5-DB 1.. * - Kartentyp: String Kartennummer: int Gültigkeit: Date 13 ERM Relationales Schema Umformung kann automatisch erfolgen Zahl der Tabellen wächst. – Problem? – Joins für Zugriffe kosten Zeit class ERM online shop Produk t - Orde r Produktnummer: int Preis: double Name: String * Info: String AnzKolli: int Gewicht: double * - Bestelldatum: Date Lieferdatum: Date Versandform: String Rechnungsnummer: int Bearbeiter: String * * * 1 * 1 Kunde Einkaufsw agen - Datum: Date Kreditk arte 1 1 - Name: String Strasse: String 1 Ort: String PLZ: int (c) schmiedecke 10 1.. * - Kartentyp: String Kartennummer: int Gültigkeit: Date SE2-5-DB 14 Datenzugriffe - SQL Datenbanksprache SQL – deklarative Sprache – Definition (DDL), Änderung (DML) und Abfrage (QL) – äußerst effizient implementiert. SELECT Name, Strasse, Ordernummer, Versanddatum FROM Kunde, Order WHERE Kunde.PLZ > 1200 AND Order.kunde = Kunde AND Versanddatum < 01-10-2010 ORDER BY Versanddatum (c) schmiedecke 10 SE2-5-DB 15 Schema-Implementierung: SQL-Export CREATE TABLE Produkt ( Produktnummer INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Preis DOUBLE NULL, Name VARCHAR(20) NULL, Info VARCHAR(255) NULL, AnzKolli INTEGER UNSIGNED NULL, Gewicht DOUBLE NULL, PRIMARY KEY(Produktnummer) ) CREATE TABLE Einkaufswagen ( idEinkaufswagen INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Datum DATE NULL, PRIMARY KEY(idEinkaufswagen) ); ... (c) schmiedecke 10 SE2-5-DB 16 Alternative: Export als XML <!--onlineshopXML.schema Generated 2008-11-06 23:57 --> <database> <name>onlineshopRDM</name> <create>1</create> <table> <name>Einkaufswagen</name> <declaration> <field> <name>idEinkaufswagen</name> <type>INTEGER</type> <default></default> <notnull>1</notnull> </field> <field> <name>Datum</name> <type>DATE</type> <default></default> <notnull>0</notnull> ... (c) schmiedecke 10 SE2-5-DB 17 Implementierte DB (c) schmiedecke 10 SE2-5-DB 18 ODBC - SQL-Nutzung aus Programmen Open Database Connectivity – Spezifikation, nicht produktgebunden – Microsoft-Entwicklung inzwischen standardisiert – BS-Bestandteil ab Windows 2000/NT C++-Programm C++-ODBC-API Programmierschnittstelle (API) für RDBMS – Registrierung der Verbindungsdaten (URL, DB-Name, User, PW) – Weitergabe von SQL-Anweisungen (Strings) an die Datenbank – Erzeugung weiterverarbeitbarer Daten aus dem SQL-Ergebnis. ODBC-Treiber für Oracle Breite Unterstützung: – Es gibt ODBC-"Treiber" für (praktisch) jedes RDBMS (unter Windows – Unix ist noch nicht so gut unterstützt) – Objektorientierte Programmiersprachen bieten APIs mit (c) schmiedecke SE2-5-DB und –Daten. Klassen zum10Umgang mit ODBC-Aufrufen OracleRDBMS 19 JDBC Java Database Connectivity – Spezifikation, nicht produktgebunden Programmierschnittstelle (API) für RDBMS – Registrierung der Verbindungsdaten (URL, DB-Name, User, PW) – Weitergabe von SQL-Anweisungen (Strings) an die Datenbank – Erzeugung weiterverarbeitbarer Java-Objekte aus dem SQLErgebnis. JDBC-"Treiber" für jede RDB-Implementierung ODBC-JDBC-"Bridge" als generischer Treiber (c) schmiedecke 10 SE2-5-DB 20 JDBC-Treiber Quelle: Jeckle, http://www.jeckle.de/vorlesung/eBusinessEng/script.html#DBAccess (c) schmiedecke 10 SE2-5-DB 21 Das JDBC-API (c) schmiedecke 10 Hinweis: Erweiterungen SE2-5-DB ab JDBC 3.0 in javax.sql 22 Die JDBC-Spezifikation (c) schmiedecke 10 SE2-5-DB 23 Arbeitsweise mit JDBC 1. 2. 3. 4. 5. 6. 7. Treiber-Bibliothek laden Verbindung zum Datenbank-Server herstellen SQL-Anweisung(en) in ein Ausführungs-Objekt packen Ausführungsobjekt ausführen Ergebnis-Objekt lesen und verarbeiten Vorgang beliebig wiederholen … irgendwann Verbindung beenden (c) schmiedecke 10 SE2-5-DB 24 DB-Verbindungen // 1. JDBC-Treiber laden Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); // oder // DriverManager.registerDriver(new com.mysql.jdbc.Driver()); // 2. Datenbank-URL spezifizieren String db_url = "jdbc:odbc:jdbc_test"; // 3. Connect zur Datenbank ausführen // (hier Kennwort beim Programmaufruf zu uebergeben) Connection my_con = DriverManager.getConnection(db_url, "java", args[0]); (c) schmiedecke 10 SE2-5-DB 25 DB-Interaktionen try { Statement stmt = connection.createStatement(); String sql = "create table newtab "+ "(id number primary key," + " name varchar2(10))"; int changes = stmt.executeUpdate(sql); // for DDL, DML sql = "Select * from newtab;"; ResultSet result = stmt.executeQuery(sql); // for QL } catch (SQLException ex) { ex.printStackTrace(); } (c) schmiedecke 10 SE2-5-DB 26 JDBC-Verbindung mit der Datenbank public class DB { private static final String dbURL = "jdbc:mysql:@localhost:3306"; private private private private static final String user = "onlineshop"; static final String password = "onlineshop"; Connection conn = null; Statement stmt; public DB () { try { DriverManager.registerDriver(new com.mysql.jdbc.Driver()); System.out.println("Driver registered sucessfully"); } catch (SQLException e) { System.err.println("Problems registering OJDBC-Driver"); e.printStackTrace(); System.exit(99); } } public void connect() throws SQLException { conn = DriverManager.getConnection(dbURL, user, password); System.out.println("Connection established sucessfully"); stmt conn.createStatement(); (c) = schmiedecke 10 SE2-5-DB } 27 JDBC-Abfrage public String[] liesProdukte() { ResultSet resultSet = null; String[]result = new String[50]; int index = 0; try { resultSet = stmt.executeQuery ("Select Name From Produkt"); while (resultSet.next()){ result[index]=resultSet.getString(1); // nicht 0!! index++; } resultSet.close(); // nicht vergessen!!! } catch (SQLException e) { e.printStackTrace(); } return result; } (c) schmiedecke 10 SE2-5-DB 28 Fazit: 1. Es geht. 2. Es geht leicht. 3. SQL-Befehle als Strings werden ungeprüft an die Datenbank geschickt... (c) schmiedecke 10 SE2-5-DB 29 ORM – Objekt-relationales Mapping JDBC ermöglicht den Zugriff auf Daten Wir wollen Persistenz von Objekten! Die Abbildung von Klassen auf Relationen (Tabellen) entspricht der Abbildung von ERM-Entitäten auf Relationen Nur die Vererbung fehlt noch. (c) schmiedecke 10 SE2-5-DB 30 ORM - Vererbung Tabelle-je-Klasse – Für jede Klasse der Hierarchie eine Tabelle – enthält nur die nicht-geerbten Attribute – Verweis auf Oberklassentabelle über OID (Primärschlüssel) – Zusatzspalte mit dem Objekttyp Daten eines Objekts auf mehrere Tabellen verteilt aufwändige Zugriffe Einzeltabelle – Tabelle enthält eigene und geerbte Attribute – Polymorphismen nur programmatisch erfassbar Tabelle-je-konkrete-Klasse – Zwischenform, weniger Redundanz, – einfachere Zugriffe als Tabelle-je-Klasse – weniger Redundanz als Einzeltabelle (c) schmiedecke 08 SE2-4-Persistenzmodelle 31 ORM: Einzeltabelle Vorteil: einfacher Zugriff ohne Join (c) schmiedecke 08 SE2-4-Persistenzmodelle 32 ORM: Tabelle-je-konkrete-Klasse Vorteil: – einfacher Zugriff ohne Join Graphik aus: Heide Balzert, Lehrbuch der Objektmodellierung Nachteil: – Änderungen der Oberklasse müssen in mehreren Tabellen durchgeführt werden. (c) schmiedecke 08 SE2-4-Persistenzmodelle 33 ORM: Tabelle-je-Klasse Vorteile: – Nahe am Klassenmodell – Änderungen in alle Klassen leicht durchzuführen Graphik aus: Heide Balzert, Lehrbuch der Objektmodellierung Nachteile: – viele Tabellen – Zugriffe über Joins (c) schmiedecke 08 SE2-4-Persistenzmodelle 34 Automatisiertes ORM Natürlich ist das ORM genauso automatisierbar wie die Abbildung ERM Relationales Modell. – Das nutzen Persistenz-Frameworks Das Ziel heißt "Transparenz": – der Programmierer soll möglichst wenig von der Persistenz merken. (c) schmiedecke 10 SE2-5-DB 35 Der "Traum" Völlige Transparenz Some Secret Mechanis m ☺ Nicht alle Objekte müssen persistent sein Klassen als "persistent" deklarieren: persistent class MyClass { ... } Nicht alle Attribute müssen persistent sein: persistent int myAttribute; Alles andere könnte "automatisch ablaufen" (c) schmiedecke 08 SE2-4-Persistenzmodelle 36 …wieder fit in Datenbanken? ☺ Nächstes Mal verbinden wir das ORM mit der Webanwendung.