Rückblick § Datenbankschnittstellen erlauben Zugriff auf Datenbank aus einer externen Anwendung § Portabilität als wichtige Anforderung, d.h. RDBMS oder Programmiersprache soll leicht austauschbar sein § Call-Level Interfaces als Schnittstellen für bestimmtes RDBMS und bestimmte Programmiersprache § Open Database Connectivity (ODBC) erreicht Entkopplung durch Verwendung von Treibern § Java Database Connectivity (JDBC) für Java-Code Datenbanken / Kapitel 11: Datenbankschnittstellen 42 Transaktionskontrolle § Beim Ausführen des ersten SQL-Kommandos über eine Verbindung (Connection) wird implizit eine neue Transaktion begonnen § Festschreiben (commit) oder Zurückrollen (rollback) der Transaktion ist mit folgenden Kommandos möglich 1 1 conn . commit (); // im try conn . rollback (); // im try Datenbanken / Kapitel 11: Datenbankschnittstellen 43 Transaktionskontrolle § Verbindung kann auf automatisches Festschreiben (auto commit) umgestellt werden, so dass jedes SQL-Kommando direkt festgeschrieben wird 1 conn . setAutoCommit ( true ); § Achtung: Bei einigen Treibern ist dies die Voreinstellung; ggf. empfiehlt es sich zuerst den aktuellen Wert mittels getAutoCommit auszulesen Datenbanken / Kapitel 11: Datenbankschnittstellen 44 Transaktionskontrolle § Isolationsstufe der Verbindung kann gesetzt werden mit der Methode setTransactionIsolation, welche eine der folgenden Konstanten als Parameter erwartet § Connection.TRANSACTION_READ_UNCOMMITTED § Connection.TRANSACTION_READ_COMMITTED § Connection.TRANSACTION_REPEATABLE_READ § Connection.TRANSACTION_SERIALIZABLE Datenbanken / Kapitel 11: Datenbankschnittstellen 45 Fehlerbehandlung (SQLException) § SQLException als Ausnahmeklasse für alle Fehler z.B. beim Verbindungsaufbau oder inkorrektem SQL 1 2 3 4 5 6 7 8 9 10 11 12 13 Connection conn = null ; Statement stmt = null ; ResultSet rs = null ; try { ... } catch ( SQLException sqle ) { System . out . println ( " Fehler : " + sqle . getMessage ()); ... // F ehler bearbe itung } finally { if ( rs != null ) try { rs . close ();} catch ( SQLException sqle ) {}; if ( stmt != null ) try { stmt . close ();} catch ( SQLException sqle ) {}; if ( conn != null ) try { conn . close ();} catch ( SQLException sqle ) {}; } § Schließen aller JDBC-Objekte, um Ressourcen auf Client (z.B. RAM) oder Server (z.B. Sockets) freizugeben Datenbanken / Kapitel 11: Datenbankschnittstellen 46 Vorkompiliertes SQL (PreparedStatement) § Anwendungen führen oft zahlreiche SQL-Kommandos gleicher Bauart auf dem RDBMS via JDBC aus § Einfügen von Datensätzen mittels INSERT 1 INSERT INTO Studenten ( MatrNr , Vorname , Name ) VALUES (? , ? , ?) § Anfragen mit Primärschlüssel als Selektionsprädikat 1 SELECT * FROM Studenten WHERE MatrNr = ? § Isolierte Ausführung jedes der baugleichen SQLKommandos ist teuer, da das RDBMS § jedes SQL-Kommando erneut parsen muss § jedes SQL-Kommando Netzwerkkommunikation erfordert Datenbanken / Kapitel 11: Datenbankschnittstellen 47 Vorkompiliertes SQL (PreparedStatement) § Vorkompiliertes SQL bietet Möglichkeit, baugleiche SQLKommandos in einer Art Schablone zusammenzufassen § das SQL-Kommando muss so nur einmal geparst werden § beim Einfügen können Gruppen (batches) von Zeilen auf einmal, mit einer Netzwerkkommunikation, eingefügt werden § JDBC stellt mit der Klasse PreparedStatement eine Klasse bereit, die solches vorkompiliertes SQL erlaubt Datenbanken / Kapitel 11: Datenbankschnittstellen 48 Vorkompiliertes SQL (PreparedStatement) § Beim Anlegen eines PreparedStatements können mittels ? Platzhalter definiert werden, die dann vor Ausführung durch konkrete Werte ersetzt werden 1 2 3 PreparedStatement pstmt = null ; // vor try pstmt = conn . prepareStatement ( " SELECT MatrNr , Name , Vorname " + " FROM Studenten WHERE MatrNr = ? " ); § Ersetzen der Platzhalter und Ausführen des Kommandos 1 2 3 long matrnr = 32781; pstmt . setLong (1 , matrnr ); rs = pstmt . executeQuery (); Datenbanken / Kapitel 11: Datenbankschnittstellen 49 Vorkompiliertes SQL (PreparedStatement) § Bei Verwendung eines PreparedStatement für INSERT Kommandos können zudem einzufügende Zeilen zu Gruppen (batches) zusammengefasst werden 1 PreparedStatement pstmt = null ; // vor try 2 3 4 // Liste mit allen Studenten LinkedList < Student > studenten = ...; 5 6 7 8 9 // Prepared Statement anlegen String insert = " INSERT INTO Studenten VALUES ( MatrNr , Vorname , Name ) " + " VALUES (? ,? ,?) " pstmt = conn . prepareStatement ( insert ); 10 11 12 13 14 15 16 17 // Einzuf ü gende Zeilen vorbereiten for ( Student : studenten ) { pstmt . set (1 , student . getMatrNr ()); pstmt . set (2 , student . getVorname ()); pstmt . set (3 , student . getName ()); pstmt . addBatch (); } 18 19 20 // Batch ausf ü hren pstmt . executeBatch (); Datenbanken / Kapitel 11: Datenbankschnittstellen 50 Vorkompiliertes SQL (PreparedStatement) § Achtung: Aktueller Batch wird im RAM des Clients zwischengespeichert; bei sehr großen Batches sollte ggf. executeBatch regelmäßig nach bestimmter Anzahl hinzugefügter Zeilen aufgerufen werden Datenbanken / Kapitel 11: Datenbankschnittstellen 51 Vergleich Statement vs. PreparedStatement § Code zum Download auf Website zur Vorlesung 1 2 3 4 5 CREATE TABLE dummy ( a int , b int , c int ) § Einfügen von 1.000.000 Zeilen per Statement und PreparedStatement in SQLite auf aktuellem Rechner (SSD, i7, 8GB RAM) § Dauer mit Statement: 18 Sekunden § Dauer mit PreparedStatement: 6 Sekunden Datenbanken / Kapitel 11: Datenbankschnittstellen 52 Ergebnis (ResultSet) § Jeder Aufruf von next einer Instanz von ResultSet liest die jeweils nächste Zeile aus dem Ergebnis § Je nach JDBC-Treiber bedeutet jeder Aufruf zudem eine Netzwerkkommunikation, d.h. jede Zeile wird separat vom RDBMS übertragen § Viele JDBC-Treiber bieten die Möglichkeit der Pufferung, d.h. Zeilen werden in Gruppen übertragen und im RAM des Clients zwischengespeichert § Zahl der zu puffernden Zeilen lässt sich mittels der Methode setFetchSize einstellen Datenbanken / Kapitel 11: Datenbankschnittstellen 53 11.5 Objekt-Relationale Abbildung (ORM) § Objekt-orientierter Entwurf (z.B. mit UML) führt zu § Klassen (z.B. Student und Vorlesung) mit § Attributen (z.B. Name oder Titel) § Assoziationen (z.B. Student hört Vorlesung) § Methoden, die „Geschäftslogik“ erfassen (z.B. Anmelden eines Student zu einer Vorlesung) § Instanzen der Klassen sollen dauerhaft (persistent) in einem RDBMS im Hintergrund, abgelegt werden Datenbanken / Kapitel 11: Datenbankschnittstellen 54 Objekt-Relationale Abbildung (ORM) § Frameworks zur objekt-relationalen Abbildung (object relational mapping) automatisieren die Erstellung entsprechenden Codes zum Lesen/Speichern der Instanzen sowie zum Anfragen z.B. § Enterprise Java Beans in Java EE § Java Data Objects und Java Persistence API § Hibernate § Relationale Datenbank im Hintergrund kann mittels ORM verborgen werden, so dass Entwickler auch ohne SQL-Kenntnisse mit den Daten arbeiten können Datenbanken / Kapitel 11: Datenbankschnittstellen 55 Anwendungsprogrammierung Objekt-relationales Mapping Objekt-Relationale Abbildung (ORM) Objekt-relationales Mapping: Prinzip Applikation Anwendungsobjekte Objektmodell Abbildungsvorschrift Laufzeitsystem Datenbankschema Sattler / Saake Datenbanken / Kapitel 11: Datenbankschnittstellen Datenbanksysteme Letzte Änderung: Nov 2015 Quelle: Saake, Sattler und Heuer [2] 11–23 56 Objektorientierter Entwurf vs. Relationenmodell § Beispiel: Klassen in Hochschulanwendung 1 2 3 4 5 6 7 public class Student { // Attribute private long matrnr ; private String vorname ; private String name ; private int semester ; private List < Vorlesung > h ö rt ; 8 // Konstruktor public Student () {...}; 9 10 11 12 13 14 15 16 17 } // Methoden public void setMatrNr ( long matrnr ) {...} public long getMatrNr () {...} public void addVorlesung ( Vorlesung vorlesung ) {...} ... Datenbanken / Kapitel 11: Datenbankschnittstellen 57 Objektorientierter Entwurf vs. Relationenmodell § Beispiel: Klassen in Hochschulanwendung 1 2 3 4 5 6 public class Vorlesung { // Attribute private long vorlnr ; private String titel ; private List < Student > h ö rer ; private Professor gelesenVon ; 7 // Konstruktor public Vorlesung () {...}; 8 9 10 11 12 13 14 15 16 } // Methoden public void setVorlNr ( long vorlnr ) {...} public long getVorlNr () {...} public void addStudent ( Student student ) {...} ... Datenbanken / Kapitel 11: Datenbankschnittstellen 58 Objektorientierter Entwurf vs. Relationenmodell § Beispiel: Klassen in Hochschulanwendung 1 2 3 4 5 6 7 public class Professor { // Attribute private long persnr ; private String vorname ; private String name ; private String fach ; private B ü ro int ; 8 // Konstruktor public Professor () {...}; 9 10 11 12 13 14 15 16 } // Methoden public void setPersNr ( long persnr ) {...} public long getPersNr () {...} ... Datenbanken / Kapitel 11: Datenbankschnittstellen 59 Objektorientierter Entwurf vs. Relationenmodell § Wie lassen sich Klassen mit ihren Attributen und Assoziationen auf Relationen abbilden? § Idee: Jede Klasse wird auf eine Relation abgebildet Professor +PersNr : int +Vorname : String +Name : String +Fach : String +Büro : int Ó Ô Professoren : [ PersNr : long, Vorname : string, Name : string, Fach : string, Büro : integer ] § Problem: Relationale Normalformen werden verletzt z.B. § mengenwertige Attribute (z.B. hörer in Vorlesung) § Redundanz als Ergebnis von 1:n und n:n Assoziationen Datenbanken / Kapitel 11: Datenbankschnittstellen 60 Objektorientierter Entwurf vs. Relationenmodell § Klassen und ihre Assoziationen müssen u.U. auf mehr als eine einzelne Relation abgebildet werden § 1:1 Assoziation als Fremdschlüsselattribut § 1:n Assoziation als Fremdschlüsselattribut oder als Fremdschlüsseltabelle § n:m Assoziation als Fremdschlüsseltabelle § Assoziationen mit Attributen auf Fremdschlüsseltabelle § vgl. Übersetzung von ERM-Diagrammen in Relationen wie in Kapitel 2 besprochen Datenbanken / Kapitel 11: Datenbankschnittstellen 61 Hibernate § Hibernate (http://hibernate.org) ist ein populäres JavaFramework für objekt-relationale Abbildung § Hibernate erhält Java-Klasse mit Abbildungsvorschrift (in XML-Datei) und kann damit Instanzen in Datenbank speichern und sie von dort lesen § Bei Navigation entlang von Assoziationen werden die verbundenen Instanzen aus der Datenbank geholt (z.B. die Studenten bei Zugriff auf hörer in Vorlesung) Datenbanken / Kapitel 11: Datenbankschnittstellen 62 Hibernate Abbildungsvorschrift in XML § Klasse muss bestimmte Anforderungen erfüllen, z.B. leeren Konstruktor haben sowie get- und set-Methoden für alle Attribute § Beispiel: Abbildungsvorschrift für Professor 1 2 3 4 5 6 7 8 9 10 11 < hibernate - mapping > < class name = " Professor " table = " Professoren " > < id name = " persnr " > < generator class = " native " / > </ id > < property name = " name " / > < property name = " vorname " / > < property name = " fach " / > < property name = " b ü ro " / > </ class > </ hibernate - mapping > Datenbanken / Kapitel 11: Datenbankschnittstellen 63 Speichern von Daten mit Hibernate § Instanz von Klasse wird angelegt und Attribute gesetzt 1 Transaction tx = null ; 2 3 4 5 6 7 8 // Professor anlegen Professor professor = new Professor (); professor . setPersNr (31415); professor . setVorname ( " Albert " ); professor . setName ( " Einstein " ); professor . setB ü ro (412); 9 10 11 12 13 14 15 16 17 // Professor speichern try { tx = session . beginTransaction (); session . save ( professor ); tx . commit (); } catch ( Hi be rn at eE xc ep ti on he ) { if ( tx != null ) tx . rollback (); } § session vorab mit Verbindungsparametern initialisiert Datenbanken / Kapitel 11: Datenbankschnittstellen 64 Anfragen mit Hibernate § Hibernate unterstützt zudem verschiedene Arten von Anfragen, die keine SQL-Kenntnisse erfordern § eigene leichtgewichtige Anfragesprache HQL § mittels Beispielinstanz (query by example) § basierend auf Kriterien (query by criteria) Datenbanken / Kapitel 11: Datenbankschnittstellen 65 Anfragen mit HQL § Hibernate hat eigene einfache Anfragesprache HQL, deren Anfragen sich auf die Namen und Attribute der Java-Klassen beziehen (nicht auf Relationen) 1 2 3 // Anfrage formulieren Query query = session . createQuery ( " from Professor where Name = ’ Einstein ’" ); 4 5 6 7 8 9 // Ergebnisse lesen Iterator iter = query . iterate (); while ( iter . hasNext ()) { Professor professor = ( Professor ) iter . next (); } Datenbanken / Kapitel 11: Datenbankschnittstellen 66 Anfragen mit Beispielinstanz (query by example) § Bei Anfragen mit Beispielinstanz wird eine Instanz erzeugt, deren Attribute die gewünschten Werte haben 1 2 3 // Beispielinstanz anlegen Professor professor = new Professor (); professor . setName ( " Einstein " ); 4 5 6 7 // Ergebnisse als Liste List < Professor > result = session . createCriteria ( Professor . class ) . add ( Example . create ( professor )). list (); Datenbanken / Kapitel 11: Datenbankschnittstellen 67 Anfragen mit Kriterien (query by criteria) § Anfrage kann durch Angabe von Kriterien mittels Methodenaufrufen erzeugt werden 1 2 3 // Ergebnisse als Liste List < Professor > res = session . createCriteria ( Professor . class ) . add ( Restrictions . eq ( " Name " , " Einstein " )). list (); Datenbanken / Kapitel 11: Datenbankschnittstellen 68 Navigation entlang Assoziationen in Hibernate § Bei Navigation entlang Assoziationen (d.h. Zugriff auf Attribute, die auf andere Attribute verweisen), werden die entsprechenden Instanzen automatisch geladen § Beispiel: Vorlesungen von Student mit MatrNr 38762 1 2 3 // Anfrage formulieren Query query = session . createQuery ( " from Student where MatrNr = 38762 " ); 4 5 6 // Student lesen Student student = ( Student ) query . list (). get (0); 7 8 9 10 11 // Vorlesungstitel ausgeben for ( Vorlesung vorlesung : student . getVorlesungen ()) { System . out . println ( vorlesung . getTitel ()); } Datenbanken / Kapitel 11: Datenbankschnittstellen 69 Ändern von Daten in Hibernate § Hibernate erlaubt es, Änderungen an Attributwerten von Instanzen zurück in die Datenbank zu schreiben § Beispiel: Erhöhe Semester aller Studenten 1 2 // T ra ns ak ti on sa nf an g Transaction tx = session . beginTransaction (); 3 4 5 6 // Anfrage formulieren Query query = session . createQuery ( " from Studenten " ); 7 8 9 10 11 12 13 // Ergebnisse lesen Iterator iter = query . iterate (); while ( iter . hasNext ()) { Student student = ( Student ) iter . next (); student . setSemester ( student . getSemester () + 1); } 14 15 16 // Ä nderungen festschreiben tx . commit (); Datenbanken / Kapitel 11: Datenbankschnittstellen 70 Zusammenfassung § JDBC erlaubt Transaktionskontrolle, d.h. Festschreiben und Zurückrollen sowie setzten der Isolationsstufe § Vorkompiliertes SQL beschleunigt die Ausführung mehrerer Kommandos gleicher Bauart signifikant § Objekt-relationale Abbildung speichert Instanzen von Klassen in relationale Datenbank; kann Datenbank und SQL vor den Entwicklern verbergen § Hibernate als populäres Java-Framework für objekt-relationale Abbildung Datenbanken / Kapitel 11: Datenbankschnittstellen 71 Literatur [1] A. Kemper und A. Eickler: Datenbanksysteme – Eine Einführung, De Gruyter Oldenbourg, 2015 (Kapitel 4) [2] G. Saake, K.-U. Sattler und A. Heuer: Datenbanken - Konzepte und Sprachen, mitp Professional, 2013 (Kapitel 13) Datenbanken / Kapitel 11: Datenbankschnittstellen 72