class: center, middle, first # Software-Entwicklung 3 ## Persistenz: SQL, NoSQL --- # Agenda 1. SQL 2. NoSQL --- class: center, middle # Was ist Persistenz? ??? * Daten über längere Zeit bereitstellen * Benötigt: Nichtflüchtiges Speichermedium * Auch nach Programmabbruch müssen die Daten wieder zur Verfügung stehen --- class: center, middle # Warum gibt es unterschiedliche Persistenzarten? ??? * Performance * Zugriffsarten * Zugriffssteuerung * Transaktionssteuerung * Unterschiedliche Anforderungen an Verfügbarkeit, Integrität, Verlässlichkeit --- # Was sind die Probleme zwischen OO und SQL-Datenbanken? > Impedance Mismatch * Datenbanken arbeiten **blockorientiert** * OO-Programme arbeiten **satzorientiert** **Übersetzung der Paradigmen notwendig! ➡️ ORM (Objekt-relationales Mapping)** --- # Basiskonzepte OO & relationale DBMS ## OO * Identität * Zustand * Verhalten * Kapselung ## relationale DBMS * Relationen * Tupel * Attribute --- # Was ist SQL? * Standard, der von relationalen DBMS (_Datenbankmanagementsysteme_) implementiert wird * Datenbanksprache für relationale DBs, bestehend aus: * Daten einfügen, ändern, löschen: **DML** _(Data Modification Language)_ * Daten abfragen inkl. sortieren, filtern, gruppieren etc.: **DQL** _(Data Query Language)_ * Datenschemas definieren: **DDL** _(Data Definition Language)_ * Verwalten von DB-Rechten: **DCL** _(Data Control Language)_ * Transaktionssteuerung: **TCL** _(Transaction Control Language)_ --- # Was sind Einsatzszenarien für relationale DBMS? * Struktur der Daten bekannt * Redundanzen und Inkosistenzen sollen vermieden werden * Transaktionen benötigt * ... --- # Was ist JDBC **Java Database Connectivity** * API zum Zugriff auf relationale DBMS * Herstellerunabhängig * Treiber für jeweiliges DBMS notwendig --- # Was sind `PreparedStatement`s? * Vorkompilierte Datenbankanweisungen * Höhere Performance als "normale" DB-Anweisungen * Mehr Sicherheit, da Typprüfung stattfindet ```java // Alle nachfolgenden Statements beziehen sich auf MariaDB // Der vollständige Verbindungsaufbau findet sich im Vorlesungsprojekt // ... PreparedStatement ps = conn.prepareStatement( "SELECT title FROM Audiotracks WHERE artist=? AND album=?"); ps.setString(1, "Glass Animals"); ps.setString(2, "Dreamland"); ResultSet rs = ps.executeQuery(); // ... ``` --- # CRUD mit JDBC: CREATE ```java // ... PreparedStatement ps = conn.prepareStatement( "INSERT INTO Audiotracks (title, path, duration, artist, album) VALUES(?, ?, ?, ?, ?) RETURNING id"); ps.setString(1, "Heat Waves"); ps.setString(2, "audio/heat_waves.mp3"); ps.setTime(3, Time.valueOf(LocalTime.parse("00:03:14"))); ps.setString(4, "Glass Animals"); ps.setString(5, "Dreamland"); ResultSet rs = ps.executeQuery(); if (rs.next()){ int dbId = rs.getInt("id"); } // ... ``` --- # CRUD mit JDBC: READ ```java // ... PreparedStatement ps = conn.prepareStatement( "SELECT title FROM Audiotracks WHERE artist=? AND album=?"); ps.setString(1, "Glass Animals"); ps.setString(2, "Dreamland"); ResultSet rs = ps.executeQuery(); while(rs.next()){ System.out.println(rs.getString(1)); } // ... ``` --- # CRUD mit JDBC: UPDATE ```java // ... PreparedStatement ps = conn.prepareStatement( "UPDATE Audiotracks SET album = ? WHERE album = ?;"); ps.setString(1, "Dreamland"); ps.setString(1, "DREAMLAND"); ps.execute(); // ... ``` --- # CRUD mit JDBC: DELETE ```java // ... PreparedStatement ps = conn.prepareStatement( "DELETE FROM Audiotracks WHERE album = ?;"); ps.setString(1, "Dreamland"); ps.execute(); // ... ``` --- # Umgang mit Objektbeziehungen Hintergrund: Wie können Objektbeziehungen abgebildet werden? ```java class AudioTrack{ // ... private Artist artist; } ``` Schritte in der DB (ggf. mit Transaktion): 1. Erzeugen eines `Artist`-Eintrags mit `INSERT` inkl. Rückgabe der erzeugten ID mit `RETURNING` 2. Speichern der zurückgegebenen ID im `Artist`-Objekt 3. Erzeugen eines `Audiotrack`-Eintrags mit `INSERT`. Setzen der Fremdschlüssel ID auf zuvorgespeicherte `Artist`-ID. --- # Ausblick: JPA **Jakarta Persistence API**/**Java Persistence API** * Vereinfachung des ORM * POJOs (_Plain old Java Objects_) können automatisch zu Tabellen gemappt werden * Möglichkeiten, Objektbeziehungen zu beschreiben und autmatisiert aufzulösen --- class: center, middle # NoSQL --- # Was ist NoSQL? **NoSQL = Not only SQL** * Sammelbegriff für unterschiedliche Datenbankentypen * Oft horizontal skalierbar ## NoSQL-Datenbanktypen * Dokumenten-DBs: z.B. MongoDB, BaseX, CouchDB * Graph-DBs: Neo4j * Key-Value-DBs: Redis * ... --- # Einsatzszenarien _[Wikipedia, 2022](https://de.wikipedia.org/w/index.php?title=NoSQL&oldid=220335513), nach [Scofield, B., 2010](http://www.slideshare.net/bscofield/nosql-codemash-2010)_
--- # CRUD mit MongoDB: CREATE _nach: https://www.mongodb.com/developer/quickstart/java-setup-crud-operations/_ ```java //... Document audioTrack = new Document("_id", new ObjectId()); audioTrack.append("title", "Heat Waves") .append("path", "audio/heat_waves.mp3") .append("duration", "00:03:14") .append("artist", "Glass Animals") .append("album", "Dreamland"); audioTracksCollection.insertOne(audioTrack); //... ``` --- # CRUD mit MongoDB: READ ```java //... Document audioTrack = audioTracksCollection.find( new Document("audiotrack_id", 10000)).first(); System.out.println(audioTrack.toJson()); //... ``` --- # CRUD mit MongoDB: UPDATE ```java import static com.mongodb.client.model.Filters.and; import static com.mongodb.client.model.Filters.eq; import static com.mongodb.client.model.Updates.*; //... Bson filter = eq("audiotrack_id", 10000); Bson updateOperation = set("album", "DREAMLAND"); UpdateResult updateResult = audioTracksCollection. updateOne(filter, updateOperation); System.out.println(audioTracksCollection.find( filter).first().toJson(prettyPrint)); System.out.println(updateResult); //... ``` --- # CRUD mit MongoDB: DELETE ```java import static com.mongodb.client.model.Filters.eq; //... Bson filter = eq("audiotrack_id", 10000); DeleteResult result = gradesCollection.deleteOne(filter); System.out.println(result); //... ``` --- # Tipps * Skripte zum befüllen der DB mit Demodaten bereitstellen * Docker-Container mit DB * SQL Inspect mit IntelliJ