diff --git a/content/2025/about/latest-changes/_index.md b/content/2025/about/latest-changes/_index.md index a29f214aec..e69de29bb2 100644 --- a/content/2025/about/latest-changes/_index.md +++ b/content/2025/about/latest-changes/_index.md @@ -1,12 +0,0 @@ -## 20260319-1542-152 - -_2026-03-19 15:42 CET auf origin/master_ - -### Seiten-Änderungen - -- **Geändert** - - [Docs / Backend (Java) / Exception Handling und Optionals](../../docs/02_java/09_java-exception_handling/) -- **Gelöscht** - - Labs / Java Labs / 09_java-exception_handling - ---- diff --git a/content/2025/labs/99_shared/database/01_setup/_index.md b/content/2025/challenges/database/01_setup/_index.md similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/_index.md rename to content/2025/challenges/database/01_setup/_index.md diff --git a/content/2025/labs/99_shared/database/01_setup/images/connection.png b/content/2025/challenges/database/01_setup/images/connection.png similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/images/connection.png rename to content/2025/challenges/database/01_setup/images/connection.png diff --git a/content/2025/labs/99_shared/database/01_setup/images/db-auswahl.png b/content/2025/challenges/database/01_setup/images/db-auswahl.png similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/images/db-auswahl.png rename to content/2025/challenges/database/01_setup/images/db-auswahl.png diff --git a/content/2025/labs/99_shared/database/01_setup/images/ende.png b/content/2025/challenges/database/01_setup/images/ende.png similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/images/ende.png rename to content/2025/challenges/database/01_setup/images/ende.png diff --git a/content/2025/labs/99_shared/database/01_setup/images/neue-verbindung.png b/content/2025/challenges/database/01_setup/images/neue-verbindung.png similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/images/neue-verbindung.png rename to content/2025/challenges/database/01_setup/images/neue-verbindung.png diff --git a/content/2025/labs/99_shared/database/01_setup/images/sql-editor.png b/content/2025/challenges/database/01_setup/images/sql-editor.png similarity index 100% rename from content/2025/labs/99_shared/database/01_setup/images/sql-editor.png rename to content/2025/challenges/database/01_setup/images/sql-editor.png diff --git a/content/2025/labs/99_shared/database/02_sql_syntax/_index.md b/content/2025/challenges/database/02_sql_syntax/_index.md similarity index 100% rename from content/2025/labs/99_shared/database/02_sql_syntax/_index.md rename to content/2025/challenges/database/02_sql_syntax/_index.md diff --git a/content/2025/labs/99_shared/database/02_sql_syntax/images/zoo-erd.png b/content/2025/challenges/database/02_sql_syntax/images/zoo-erd.png similarity index 100% rename from content/2025/labs/99_shared/database/02_sql_syntax/images/zoo-erd.png rename to content/2025/challenges/database/02_sql_syntax/images/zoo-erd.png diff --git a/content/2025/labs/99_shared/database/_index.md b/content/2025/challenges/database/_index.md similarity index 100% rename from content/2025/labs/99_shared/database/_index.md rename to content/2025/challenges/database/_index.md diff --git "a/content/2025/labs/99_shared/database/solutions/L\303\266sung Onlineshop ERD.drawio" "b/content/2025/challenges/database/solutions/L\303\266sung Onlineshop ERD.drawio" similarity index 100% rename from "content/2025/labs/99_shared/database/solutions/L\303\266sung Onlineshop ERD.drawio" rename to "content/2025/challenges/database/solutions/L\303\266sung Onlineshop ERD.drawio" diff --git "a/content/2025/labs/99_shared/database/solutions/L\303\266sung Onlineshop ERD.png" "b/content/2025/challenges/database/solutions/L\303\266sung Onlineshop ERD.png" similarity index 100% rename from "content/2025/labs/99_shared/database/solutions/L\303\266sung Onlineshop ERD.png" rename to "content/2025/challenges/database/solutions/L\303\266sung Onlineshop ERD.png" diff --git a/content/2025/labs/99_shared/database/solutions/Solution_SQL_Murder_Mystery.txt b/content/2025/challenges/database/solutions/Solution_SQL_Murder_Mystery.txt similarity index 100% rename from content/2025/labs/99_shared/database/solutions/Solution_SQL_Murder_Mystery.txt rename to content/2025/challenges/database/solutions/Solution_SQL_Murder_Mystery.txt diff --git a/content/2025/challenges/java/java-ood/02_Vehicles/_index.md b/content/2025/challenges/java/java-ood/02_Vehicles/_index.md index fd3e9ce1b4..4620a38ffe 100644 --- a/content/2025/challenges/java/java-ood/02_Vehicles/_index.md +++ b/content/2025/challenges/java/java-ood/02_Vehicles/_index.md @@ -3,8 +3,6 @@ title: "Objektorientiertes Design Challenge - Vehicles" linkTitle: "Objektorientiertes Design Challenge - Vehicles" type: docs weight: 4 -description: > - Challenge zu Modul #J3 - Vehicles --- Entwirf ein Fahrzeugverwaltungssystem für ein Autohaus. diff --git a/content/2025/docs/99_shared/database/01_db-erklaert/_index.md b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/_index.md similarity index 99% rename from content/2025/docs/99_shared/database/01_db-erklaert/_index.md rename to content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/_index.md index 6fa92c74bb..dc99a69ca4 100644 --- a/content/2025/docs/99_shared/database/01_db-erklaert/_index.md +++ b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/_index.md @@ -67,7 +67,7 @@ Um sicherzustellen, dass SQL in verschiedenen Datenbanksystemen wie **MariaDB, P Allerdings implementieren viele Datenbanksysteme zusätzliche SQL-Erweiterungen, die nicht im ANSI-Standard enthalten sind. Deshalb kann sich die SQL-Syntax je nach System leicht unterscheiden. Im IT-Ninjas werden wir hauptsächlich mit **MariaDB** arbeiten. -Mehr Informationen zur SQL-Syntax findest du im Kapitel [SQL Syntax](../02_sql-syntax/). +Mehr Informationen zur SQL-Syntax findest du im Kapitel [SQL Syntax](../02_sql-basics/). #### SQL Datentypen diff --git a/content/2025/docs/99_shared/database/01_db-erklaert/images/begriffe-relationaler-datenbanken.png b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/begriffe-relationaler-datenbanken.png similarity index 100% rename from content/2025/docs/99_shared/database/01_db-erklaert/images/begriffe-relationaler-datenbanken.png rename to content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/begriffe-relationaler-datenbanken.png diff --git a/content/2025/docs/99_shared/database/01_db-erklaert/images/beispiel-bank.drawio b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/beispiel-bank.drawio similarity index 100% rename from content/2025/docs/99_shared/database/01_db-erklaert/images/beispiel-bank.drawio rename to content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/beispiel-bank.drawio diff --git a/content/2025/docs/99_shared/database/01_db-erklaert/images/beispiel-bank.png b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/beispiel-bank.png similarity index 100% rename from content/2025/docs/99_shared/database/01_db-erklaert/images/beispiel-bank.png rename to content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/beispiel-bank.png diff --git a/content/2025/docs/99_shared/database/01_db-erklaert/images/nosql-databases.jpg b/content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/nosql-databases.jpg similarity index 100% rename from content/2025/docs/99_shared/database/01_db-erklaert/images/nosql-databases.jpg rename to content/2025/docs/02_java/10_java-jdbc/01_Database_Introduction/images/nosql-databases.jpg diff --git a/content/2025/docs/99_shared/database/02_sql-syntax/_index.md b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/_index.md similarity index 78% rename from content/2025/docs/99_shared/database/02_sql-syntax/_index.md rename to content/2025/docs/02_java/10_java-jdbc/02_sql-basics/_index.md index 1115d8e474..ea0382ee8d 100644 --- a/content/2025/docs/99_shared/database/02_sql-syntax/_index.md +++ b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/_index.md @@ -297,6 +297,8 @@ welches in beiden Tabellen vertreten ist. So wird dann die Verbindung hergestell Bei Joins gibt es viele verschiedene und teilweise sehr komplexe Varianten, welche auch dementsprechend selten benutzt werden. Wir schauen uns hier die vier wichtigsten an. +Da diese nicht oft in der Praxis zum Einsatz kommen, sind Right-, Left- sowie auch Full-Join in dieser Doku optional. + ### Inner Join (_join_) Der Inner Join ist der wichtigste und am meisten benötigte Join. Der Inner Join verbindet die Tabellen und gibt nur @@ -313,7 +315,7 @@ Das dazugehörige Statement würde so aussehen: SELECT * FROM tabelle_a INNER JOIN tabelle_b ON tabelle_a.id = tabelle_b.id; ``` -### Right und Left Join +### Right und Left Join (Optional) Im Vergleich zum Inner Join wird beim Right und Left Join nicht nur die Schnittmenge, sondern auch noch eine äussere Menge zurückgegeben. Grafisch würde das so aussehen: @@ -397,7 +399,7 @@ Resultat: > beruf_id ist doppelt, da es in beiden Tabellen ein Attribut mit diesem Namen gibt. Könnte mit der Auswahl im Select > auch ausgeblendet werden. -### Full Join +### Full Join (Optional) Der Full Join ist sehr eng mit dem Left und Right Join verwandt. Jetzt werden jedoch alle Werte zurückgegeben. Wenn kein Gegenstück zu einem Wert vorhanden ist, werden diese gleich wie beim Left und Right Join mit `null` angegeben. Grafisch @@ -443,194 +445,48 @@ Resultat: ## Aggregationen & weiteres In diesem Abschnitt gehen wird auf Aggregationen und weitere wichtige Syntax-Elemente ein. Aggregationen in SQL sind -Funktionen, die verwendet werden, um zusammengefasste Informationen aus großen Datenmengen zu erhalten. +Funktionen, die verwendet werden, um zusammengefasste Informationen aus grossen Datenmengen zu erhalten. Dadurch wird es einfacher, die Daten zu analysieren und Muster oder Trends zu erkennen. +Dazu gehören unter anderem: ### Count -Die Aggregation Count zählt wie viele Resultate das beim Query zurückgegeben werden. Count funktioniert bei allen -Datentypen gleich und muss nicht angepasst werden. Hier ein Beispiel zu Count: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Schüler/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Maurer/in | -| Leo | Leonidas | 35 | `null` | - -Statement: +Die Aggregation Count zählt wie viele Resultate das beim Query zurückgegeben werden. ```sql SELECT COUNT(*), COUNT(beruf) FROM person; ``` -Resultat: - -| count(\*) | count(beruf) | -| --------- | ------------ | -| 5 | 4 | - -Aus dem Resultat lässt sich schliessen, dass NULL-Werte im Count nicht beachtet werden. - ### Max/Min -Die Aggregationen Max und Min sind logischerweise zum Finden des grössten und kleinsten Wertes. Beide funktionieren -bei allen Datentypen, jedoch haben sie beispielsweise bei einem String einen anderen Weg das Maximum und Minimum zu -finden. Dort wird anhand einer Collation (Sortierungsregel) das Maximum und Minimum bestimmt. Bei normalen Zahlen sieht -es so aus: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Schüler/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Maurer/in | -| Leo | Leonidas | 35 | `null` | - -Statement: +Die Aggregationen Max und Min sind logischerweise zum Finden des grössten und kleinsten Wertes. ```sql SELECT MAX(alter), MIN(alter) FROM person; ``` -Resultat: - -| max(alter) | min(alter) | -| ---------- | ---------- | -| 52 | 13 | - ### Sum Sum summiert die Werte einer Spalte. Im Gegensatz zu den vorherigen Aggregationen funktioniert Sum nur mit Zahlenwerten. -Bei Strings oder ähnlichem wird ein Fehler zurückgegeben. Hier ein Beispiel zur Verwendung von Sum: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Schüler/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Maurer/in | -| Leo | Leonidas | 35 | `null` | - -Statement: ```sql SELECT SUM(alter) FROM person; ``` -Resultat: - -| sum(alter) | -| ---------- | -| 144 | - ### Avg -Um den Durchschnitt von Zahlen zu finden wird die Funktion AVG verwendet. Gleich wie Sum funktioniert Avg nur mit Zahlen. -Hier ein Beispiel zu avg: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Schüler/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Maurer/in | -| Leo | Leonidas | 35 | `null` | - -Statement: +Um den Durchschnitt von Zahlen zu finden wird die Funktion AVG verwendet. ```sql SELECT AVG(alter) FROM person; ``` -Resultat: - -| avg(alter) | -| ---------- | -| 28.8 | - -### Order By - -Das Keyword Order By ist zum Sortieren des Resultats sehr nützlich. Zusammen mit ASC (=Ascending, Aufsteigend) und DESC -(=Descending, Absteigend) kann das Resultat auf verschiedenste Weisen nach einem oder mehreren Attributen sortiert -werden. Standardmässig verwendet Order By ASC, daher kann das ASC im Query auch weggelassen werden. Beispiel zu Order By: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Schüler/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Maurer/in | -| Leo | Leonidas | 35 | `null` | - -Statement ASC: - -```sql -SELECT vorname, alter FROM person ORDER BY alter ASC; -``` - -Resultat: - -| vorname | alter | -| ------- | ----- | -| Anja | 13 | -| Max | 18 | -| Fritz | 26 | -| Leo | 35 | -| Hans | 52 | - -Statement DESC: - -```sql -SELECT vorname, alter FROM person ORDER BY alter DESC; -``` - -Resultat: - -| vorname | alter | -| ------- | ----- | -| Hans | 52 | -| Leo | 35 | -| Fritz | 26 | -| Max | 18 | -| Anja | 13 | - ### Group By -Mit Group By können Tupel mit gleichen Werten bei einem Attribut zusammen geführt werden, um beispielsweise in einem -Count gezählt zu werden. Wie bei Order By kann ein Resultat mehrfach gruppiert werden. Hier ein einfaches Beispiel zu -Order By: - -Ausgangstabelle Person: - -| vorname | nachname | alter | beruf | -| ------- | ---------- | ----- | ------------------ | -| Anja | Ackermann | 13 | Hochbauzeichner/in | -| Fritz | Fischer | 26 | Pilot/in | -| Hans | Hansen | 52 | Hochbauzeichner/in | -| Max | Mustermann | 18 | Pilot/in | -| Leo | Leonidas | 35 | Pilot/in | - -Statement: +Mit Group By können Tupel mit gleichen Werten bei einem Attribut zusammen geführt werden, um beispielsweise in einem Count gezählt zu werden. ```sql SELECT COUNT(*), beruf FROM person GROUP BY beruf; ``` -Resultat: - -| count(\*) | beruf | -| --------- | ------------------ | -| 2 | Hochbauzeichner/in | -| 3 | Pilot/in | +- Wie diese angewendet werden findest du hier: https://mariadb.com/docs/server/reference/sql-functions/aggregate-functions diff --git a/content/2025/docs/99_shared/database/02_sql-syntax/images/full-join.png b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/full-join.png similarity index 100% rename from content/2025/docs/99_shared/database/02_sql-syntax/images/full-join.png rename to content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/full-join.png diff --git a/content/2025/docs/99_shared/database/02_sql-syntax/images/inner-join.png b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/inner-join.png similarity index 100% rename from content/2025/docs/99_shared/database/02_sql-syntax/images/inner-join.png rename to content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/inner-join.png diff --git a/content/2025/docs/99_shared/database/02_sql-syntax/images/left-join.png b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/left-join.png similarity index 100% rename from content/2025/docs/99_shared/database/02_sql-syntax/images/left-join.png rename to content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/left-join.png diff --git a/content/2025/docs/99_shared/database/02_sql-syntax/images/right-join.png b/content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/right-join.png similarity index 100% rename from content/2025/docs/99_shared/database/02_sql-syntax/images/right-join.png rename to content/2025/docs/02_java/10_java-jdbc/02_sql-basics/images/right-join.png diff --git a/content/2025/docs/99_shared/database/03_constraints/_index.md b/content/2025/docs/02_java/10_java-jdbc/03_constraints/_index.md similarity index 100% rename from content/2025/docs/99_shared/database/03_constraints/_index.md rename to content/2025/docs/02_java/10_java-jdbc/03_constraints/_index.md diff --git a/content/2025/docs/02_java/10_java-jdbc/04_jdbc/_index.md b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/_index.md new file mode 100644 index 0000000000..d59a483bb7 --- /dev/null +++ b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/_index.md @@ -0,0 +1,221 @@ +--- +title: "JDBC (Java Database connection)" +linkTitle: "JDBC (Java Database connection)" +weight: 4 +--- + +#### Ziele + +- Ich weiss was die JDBC-Schnittstelle ist und wofür sie benutzt wird +- Ich weiss was JDBC-Treiber sind und warum sie benötigt werden +- Ich kenne die wichtigsten Interfaces der JDBC-Schnittstelle +- Ich weiss wie parametrisierte SQL-Anweisungen verwendet werden können +- Ich kann eine Datenbank-Verbindung aus einer Java-Anwendung herstellen +- Ich kann CRUD-Operationen aus einer Java-Anwendung ausführen + +## Einleitung + +Die meisten Apps und Webseiten, welche wir heutzutage fast täglich verwenden, dienen lediglich der Datenverarbeitung. +Sobald du ein Bild deines Freundes likest, den Fahrplan abrufst oder eine neue Tastatur bestellst, +es werden immer Daten gelesen, geschrieben, bearbeitet oder gelöscht. +Es gibt Frameworks (darunter z.B. Spring), welche die Verbindung zu Datenbanken verwalten und die sog. +"Boiler-Plate"-Details dazu von den Entwicklern verbergen. Diese Frameworks bieten auch einfache +Interaktion mit der Datenbank z.B. im Form von CRUD-Operationen. +Durch das Verwenden solcher Frameworks kann auf "Boiler-Plate" Code verzichtet werden. +Die Entwicklung von Business-Logik ist somit von infrastrukturellen Details getrennt. + +Es gibt jedoch Situationen, wo solche Frameworks nicht benutzt werden können oder man muss bestimmte +Aktivitäten, welche diese Frameworks out-of-the-box anbieten, anders gestalten. +In solchen Situationen kann die JDBC-Bibliothek von Java verwendet werden. + +## Was ist JDBC + +JDBC ist eine Schnittstelle, welche dafür benutzt wird, um aus einer Java Anwendung eine Verbindung +zu einer Datenbank herzustellen und Queries auf den Daten darin (z.B. lesen oder bearbeiten) ausführen zu können. +Die JDBC-Schnittstelle stellt eine Datenbank unabhängige API zur Verfügung und trägt damit dazu bei, dass +die Anwendung nicht an einer bestimmten Datenbank stark gekoppelt ist (sprich, die Anwendung muss die +unterliegende Datenbank, theoretisch, gar nicht kennen). + +Um die eigentliche Verbindung mit der Datenbank zu ermöglichen, werden JDBC-Treiber eingesetzt. +Ein JDBC-Treiber ist eine Software-Komponente, welche die Zugriffstechnik für eine bestimmte Datenbank +(z.B. Oracle, Postgres usw.) kennt und somit in der Lage ist, Anfragen an der Datenbank weiterzuleiten +wie auch die Ergebnisse zurückzuliefern. Solche Treiber können umgetauscht werden, wenn die unterliegende Datenbank +geändert werden soll, ohne dass es zu einer Anpassung in der Anwendung-Code kommt. + +Eine vereinfachte Darstellung der JDBC-Architektur sieht also wie folgt aus: + +![](images/jdbc-architektur.png "JDBC-Architektur") + +## JDBC in der Praxis + +Die Klassen und Interfaces der JDBC-Schnittstelle befinden sich im Paket "java.sql". +Entsprechend reicht ein "import"-Statement um mit diesen Klassen/Interfaces arbeiten zu können. +Die JDBC-Treiber sind jedoch separate und proprietäre Komponenten, welche zur Laufzeit vorhanden sein müssen +damit der Classloader sie wirklich laden kann. Bei einem Maven-Projekt wird dies mittels einer Maven-Abhängigkeit +erledigt. Ansonsten muss die Jar-Datei des Treibers auf dem Klassenpfad vorhanden sein. + +Die ersten Schritte bei der Arbeit mit der JDBC-Schnittstelle beinhalten die nötige Konfiguration um die +Verbindung zur Datenbank herstellen zu können. Anschliessend können Abfragen und sonstige +SQL-Anweisungen ausgeführt werden. + +Die folgenden Abschnitte zeigen die nötigen Schritte anhand von Beispielen. +Diese Beispiele wurden in einem Maven-Projekt ohne das Spring-Framework erstellt. + +### Maven-Dependency + +Sobald die gewünschte Datenbank festgelegt wurde, kann der dazugehörende JDBC-Treiber als +Maven-Abhängigkeit herangezogen werden. + +Das folgende Beispiel zeigt eine Abhängigkeit zu einem MySQL-Treiber: + +![dependency.png](images/dependency.png) + +Die restlichen Schritte erfolgen im Java-Code. + +### Treiber laden/registrieren + +**Hinweis** +Dieser Schritt wird nur bei JDBC-Versionen benötigt, welche älter sind als die Version 4! +Bei neueren Versionen, werden alle Treiber geladen, welche auf dem Klassenpfad gefunden werden und +somit braucht es diesen Schritt nicht mehr. + +Mit der statischen Methode _forName_ von _Class_ wird die Klasse _Driver_ geladen. +Hier geht es um die Datenbank spezifischer Treiber, welche es der Anwendung den Datenzugriff auf der +gewünschten Datenbank ermöglicht. + +Im folgenden Beispiel wird der JDBC-Treiber für MySQL registriert: + +![](images/driver_registration.png) + +### Datenbankverbindung herstellen + +Der Zugriff auf einer Datenbank erfordert die Konfiguration folgender Elemente: + +- url: eine JDBC-URL, welche auf die gewünschte Datenquelle zeigt +- Benutzername: einer, für den Zugriff auf die Datenbank, autorisierter Benutzer +- Passwort: das Passwort des autorisierten Benutzers, womit er sich authentifizieren kann + +![](images/connection_configuration.png) + +Die Konfiguration wird hier einfachheitshalber als Klartext im Code geschrieben. +Selbstverständlich dürfen vertrauliche Informationen wie z.B. das Passwort nicht als Klartext im Code stehen. +Für diesen Zweck, wie auch für die Konfiguration unterschiedlichen Umgebungen, eignen sich System- +oder Umgebungsvariablen (mit oder ohne Verschlüsselung) besser. + +Die obige Konfiguration kann nun für die Herstellung einer Datenbankverbindung verwendet werden. +Dazu wird die statische Methode `getConnection` der Klasse `DriverManager` verwendet: + +![](images/connection_creation.png) + +Ab diesem Punkt repräsentiert das Connection-Objekt die Verbindung zur Datenbank. + +### SQL-Anweisung vorbereiten + +Die SQL-Anweisung kann als String vor der Ausführung vorbereitet werden: + +![](images/select_query_no_params.png) + +Wenn eine IDE wie z.B. IntelliJ verwendet wird und eine Datasource mit der richtigen Datenbank definiert wird, +erkennt die IDE, dass es sich um eine SQL-Anweisung handelt und liefert entsprechend +Vorschläge und formatiert die Anweisung richtig und gut leserlich. + +Die obige SQL-Anweisung dient dazu alle Daten aus einer bestehenden Tabelle zu Lesen. +SQL-Anweisungen können aber auch Operationen wie Tabellen erstellen, Daten einfügen, löschen oder +bearbeiten usw. beinhalten. + +Als Beispiel, erstellt die folgende SQL-Anweisung eine Tabelle - falls diese noch nicht existiert - +mit ein paar gewünschten Attributen (Spalten): + +![](images/create_table_query.png) + +### SQL-Anweisung ausführen + +Um SQL-Anweisungen ausführen zu können wird zunächst ein Statement-Objekt aus dem vorhandenen +Connection-Objekt erzeugt. Dieses Statement-Objekt wird verwendet, um die SQL-Anweisung an die +Datenbank zu richten. Dazu wird eine der _execute_ Methoden des Statement-Objektes verwendet. + +Im folgenden Beispiel wird die ein Statement-Objekt mithilfe des Connection-Objekt erstellt. +Danach wird die Methode _executeQuery_ verwendet, welche eine SQL-Anweisung als +Parameter entgegennimmt, diese ausführt und eine Referenz auf die Ergebnismenge (sog. ResultSet) zurückliefert: + +![](images/statement_exectution.png) + +### Parametrisierte SQL-Anweisungen + +Bis jetzt haben wir SQL-Anweisungen ausgeführt, welche keine Einschränkungen beinhaltet haben. +Oft werden jedoch SQL-Anweisungen mit bestimmten Kriterien oder Einschränkungen benötigt damit die +zurückgelieferten Daten anhand dieser Kriterien gefiltert werden können. +In solchen Situationen wird der SQL "WHERE"-Befehl benutzt. Zum Beispiel: + +_SELECT \* FROM user WHERE username = 'gandalf' and age > 20;_ + +In diesem Beispiel, werden nur Einträge zurückgeliefert, welche die Kriterien _username = 'gandalf'_ +und _age > 20_ erfüllen. +Wenn nun dieselbe Anweisung mehrmals ausgeführt werden soll aber jeweils mit anderen Parameter (also mit unterschiedlichen _username_ und _age_), +wird die Anweisung mit Platzhaltern wie folgt geschrieben (ein Fragezeichen dient als einen Platzhalter): + +![](images/query_with_placeholder.png) + +Für das eigentliche Ausführen der Anweisung müssen alle Platzhalter durch konkrete Werte ersetzt werden. +Dazu wird ein _PreparedStatement_ verwendet, welche es erlaubt, alle Platzhalter anhand ihrer Position (beginnend mit 1) +mittels _setXXX_ Methoden anzusprechen und mit den konkreten Werten zu ersetzen. +Anschliessend, kann auch hier eine der _executeXXX_ Methoden verwendet werden, um die Anweisung auszuführen: +Für das eigentliche Ausführen der Anweisung müssen alle Platzhalter durch konkrete Werte ersetzt werden. +Dazu wird ein `PreparedStatement` verwendet, welche es erlaubt, alle Platzhalter anhand ihrer Position (beginnend mit 1) +mittels `setXXX` Methoden anzusprechen und mit den konkreten Werten zu ersetzen. +Anschliessend, kann auch hier eine der `executeXXX` Methoden verwendet werden, um die Anweisung auszuführen: +![](images/prepared_statement.png) + +### Rückgabewerte verarbeiten + +Bei der Ausführung von bestimmten SQL-Anweisungen (z.B. bei SELECT Operationen), wird eine Ergebnismenge zurückgeliefert. +Ein ResultSet repräsentiert einen sog. _Cursor_ auf diese Ergebnismenge. +Die Methoden des ResultSets, bewegen den Cursor (je nach Art des Cursors) vorwärts, rückwärts, zur ersten oder zur letzten Position usw. +Somit kann über die gesamte Ergebnismenge, Zeile bei Zeile, iteriert werden, um die Werte zu lesen. + +![](images/resultset_iteration.png) + +Im obigen Beispiel wird die _next_ Methode verwendet um den Cursor jeweils eine Zeile vorwärtszubewegen. +Aus jeder Zeile werden aus dem ResultSet mittels _getXXX_ Methoden (XXX steht für den Typ des Wertes) +die Werte, welche in dieser aktuellen Zeile vorhanden sind. +Die _getXXX_ Methoden, bekommen als Parameter entweder die Spaltenposition oder den Spaltennamen, welche gelesen werden soll. +Bei einer Spaltenposition hat die erste zurückgelieferte Spalte die Position 1. +Hinter der letzten Zeile liefert die _next_ Methode _false_ zurück und somit wird die Schleife beendet, +nachdem alle Zeilen bearbeitet worden sind. + +### Verbindungen schliessen + +Objekte der Typ `Connection`, `Statement` oder auch `PreparedStatement` sind sog. Ressourcen. +Solche Ressourcen müssen nach Verbrauch wieder explizit geschlossen werden: + +![](images/close_statement_and_connection.png) + +Wenn diese Ressourcen innerhalb eines try-with-resources Befehls erstellt werden, entfällt diese +explizite Schliessung der Ressourcen. +Die Arbeit mit try-with-resources ist immer vorzuziehen, wenn es um Closable-Ressourcen geht. + +### Zusammenfassung + +Die folgende Beispiel-Methode fasst die oben erwähnten Arbeitsschritte mit JDBC (aktuelle Version) zusammen: + +```java +private static void findByUsernameAndAge(String url, String dbUsername, String password, String username, int age) throws SQLException { + try(Connection connection = DriverManager.getConnection(url, dbUsername, password)) { + String query = "SELECT * FROM user WHERE username = ? and age > ?"; + + try(PreparedStatement statement = connection.prepareStatement(query)){ + statement.setString(1, username); + statement.setInt(2, age); + + ResultSet resultSet = statement.executeQuery(); + + while(resultSet.next()){ + String data = resultSet.getInt(1) + ":" + resultSet.getString(2); + System.out.println(data); + } + } + } +} +``` + +--- diff --git a/content/2025/docs/02_java/10_java-jdbc/images/close_statement_and_connection.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/close_statement_and_connection.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/close_statement_and_connection.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/close_statement_and_connection.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/connection_configuration.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/connection_configuration.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/connection_configuration.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/connection_configuration.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/connection_creation.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/connection_creation.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/connection_creation.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/connection_creation.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/create_table_query.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/create_table_query.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/create_table_query.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/create_table_query.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/dependency.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/dependency.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/dependency.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/dependency.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/driver_registration.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/driver_registration.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/driver_registration.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/driver_registration.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/jdbc-architektur.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/jdbc-architektur.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/jdbc-architektur.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/jdbc-architektur.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/prepared_statement.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/prepared_statement.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/prepared_statement.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/prepared_statement.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/query_with_placeholder.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/query_with_placeholder.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/query_with_placeholder.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/query_with_placeholder.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/resultset_iteration.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/resultset_iteration.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/resultset_iteration.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/resultset_iteration.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/select_query_no_params.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/select_query_no_params.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/select_query_no_params.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/select_query_no_params.png diff --git a/content/2025/docs/02_java/10_java-jdbc/images/statement_exectution.png b/content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/statement_exectution.png similarity index 100% rename from content/2025/docs/02_java/10_java-jdbc/images/statement_exectution.png rename to content/2025/docs/02_java/10_java-jdbc/04_jdbc/images/statement_exectution.png diff --git a/content/2025/docs/99_shared/database/04_datenbank-design/_index.md b/content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/_index.md similarity index 97% rename from content/2025/docs/99_shared/database/04_datenbank-design/_index.md rename to content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/_index.md index a57f1bf6f0..32489607da 100644 --- a/content/2025/docs/99_shared/database/04_datenbank-design/_index.md +++ b/content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/_index.md @@ -1,9 +1,11 @@ --- -title: "Datenbank Design" -linkTitle: "Datenbank Design" -weight: 4 +title: "Datenbank Design (Optional)" +linkTitle: "Datenbank Design (Optional)" +weight: 5 --- +Die Inhalte dieses Moduls sind wichtig für die künftige Datenbank Entwicklung. Da diese Themen für die Labs nicht zwingend gebraucht werden, sind diese optional. + ## Ziele - Du weisst was Normalisierung ist und wieso sie wichtig ist. @@ -309,6 +311,7 @@ Höhere Normalformen wie die **Boyce-Codd-Normalform (BCNF)** oder die **vierte In diesem Abschnitt betrachten wir die beiden Begriffe **ERM (Entity-Relationship-Modell)** und **ERD (Entity-Relationship-Diagramm)**. Es ist wichtig, den Unterschied zwischen den beiden zu verstehen. +Entity Relationship Diagramme sowie Modelle werden oft benutzt und es ist wichtig diese erstellen zu können. Für die Labs werden diese allerdings nicht zwingend gebraucht. ### Entity-Relationship-Modell (ERM) @@ -438,4 +441,4 @@ Diese zusätzliche Tabelle ermöglicht eine **eindeutige Zuordnung** zwischen B Die Kardinalität ist ein wichtiger Bestandteil des **Entity-Relationship-Modells (ERM)** und beschreibt, wie Entitäten miteinander verknüpft sind. Das Verständnis der Kardinalitäten hilft, eine **optimale Datenbankstruktur** zu entwickeln, die **Redundanzen vermeidet** und **Datenkonsistenz sicherstellt**. -![task1](/images/task.png) Jetzt bist du dran. Löse bitte die [Aufgaben zu Datenbanken](../../../../labs/99_shared/database/) in den Labs. +![task1](/images/task.png) Jetzt bist du dran. Löse bitte diese [Aufgabe](../../../../labs/02_java/11_java-jdbc/01_Jdbc_Exercises) in den Labs. diff --git a/content/2025/docs/99_shared/database/04_datenbank-design/images/buch-erd.drawio b/content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/images/buch-erd.drawio similarity index 100% rename from content/2025/docs/99_shared/database/04_datenbank-design/images/buch-erd.drawio rename to content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/images/buch-erd.drawio diff --git a/content/2025/docs/99_shared/database/04_datenbank-design/images/buch-erd.png b/content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/images/buch-erd.png similarity index 100% rename from content/2025/docs/99_shared/database/04_datenbank-design/images/buch-erd.png rename to content/2025/docs/02_java/10_java-jdbc/05_datenbank-design/images/buch-erd.png diff --git a/content/2025/docs/02_java/10_java-jdbc/_index.md b/content/2025/docs/02_java/10_java-jdbc/_index.md index cbd6d5072e..87bcf2fd09 100644 --- a/content/2025/docs/02_java/10_java-jdbc/_index.md +++ b/content/2025/docs/02_java/10_java-jdbc/_index.md @@ -6,217 +6,6 @@ description: > Modul #J7 - JDBC --- -#### Ziele - -- Ich weiss was die JDBC-Schnittstelle ist und wofür sie benutzt wird -- Ich weiss was JDBC-Treiber sind und warum sie benötigt werden -- Ich kenne die wichtigsten Interfaces der JDBC-Schnittstelle -- Ich weiss wie parametrisierte SQL-Anweisungen verwendet werden können -- Ich kann eine Datenbank-Verbindung aus einer Java-Anwendung herstellen -- Ich kann CRUD-Operationen aus einer Java-Anwendung ausführen - -## Einleitung - -Die meisten Apps und Webseiten, welche wir heutzutage fast täglich verwenden, dienen lediglich der Datenverarbeitung. -Sobald du ein Bild deines Freundes likest, den Fahrplan abrufst oder eine neue Tastatur bestellst, -es werden immer Daten gelesen, geschrieben, bearbeitet oder gelöscht. -Es gibt Frameworks (darunter z.B. Spring), welche die Verbindung zu Datenbanken verwalten und die sog. -"Boiler-Plate"-Details dazu von den Entwicklern verbergen. Diese Frameworks bieten auch einfache -Interaktion mit der Datenbank z.B. im Form von CRUD-Operationen. -Durch das Verwenden solcher Frameworks kann auf "Boiler-Plate" Code verzichtet werden. -Die Entwicklung von Business-Logik ist somit von infrastrukturellen Details getrennt. - -Es gibt jedoch Situationen, wo solche Frameworks nicht benutzt werden können oder man muss bestimmte -Aktivitäten, welche diese Frameworks out-of-the-box anbieten, anders gestalten. -In solchen Situationen kann die JDBC-Bibliothek von Java verwendet werden. - -## Was ist JDBC - -JDBC ist eine Schnittstelle, welche dafür benutzt wird, um aus einer Java Anwendung eine Verbindung -zu einer Datenbank herzustellen und Queries auf den Daten darin (z.B. lesen oder bearbeiten) ausführen zu können. -Die JDBC-Schnittstelle stellt eine Datenbank unabhängige API zur Verfügung und trägt damit dazu bei, dass -die Anwendung nicht an einer bestimmten Datenbank stark gekoppelt ist (sprich, die Anwendung muss die -unterliegende Datenbank, theoretisch, gar nicht kennen). - -Um die eigentliche Verbindung mit der Datenbank zu ermöglichen, werden JDBC-Treiber eingesetzt. -Ein JDBC-Treiber ist eine Software-Komponente, welche die Zugriffstechnik für eine bestimmte Datenbank -(z.B. Oracle, Postgres usw.) kennt und somit in der Lage ist, Anfragen an der Datenbank weiterzuleiten -wie auch die Ergebnisse zurückzuliefern. Solche Treiber können umgetauscht werden, wenn die unterliegende Datenbank -geändert werden soll, ohne dass es zu einer Anpassung in der Anwendung-Code kommt. - -Eine vereinfachte Darstellung der JDBC-Architektur sieht also wie folgt aus: - -![](./images/jdbc-architektur.png "JDBC-Architektur") - -## JDBC in der Praxis - -Die Klassen und Interfaces der JDBC-Schnittstelle befinden sich im Paket "java.sql". -Entsprechend reicht ein "import"-Statement um mit diesen Klassen/Interfaces arbeiten zu können. -Die JDBC-Treiber sind jedoch separate und proprietäre Komponenten, welche zur Laufzeit vorhanden sein müssen -damit der Classloader sie wirklich laden kann. Bei einem Maven-Projekt wird dies mittels einer Maven-Abhängigkeit -erledigt. Ansonsten muss die Jar-Datei des Treibers auf dem Klassenpfad vorhanden sein. - -Die ersten Schritte bei der Arbeit mit der JDBC-Schnittstelle beinhalten die nötige Konfiguration um die -Verbindung zur Datenbank herstellen zu können. Anschliessend können Abfragen und sonstige -SQL-Anweisungen ausgeführt werden. - -Die folgenden Abschnitte zeigen die nötigen Schritte anhand von Beispielen. -Diese Beispiele wurden in einem Maven-Projekt ohne das Spring-Framework erstellt. - -### Maven-Dependency - -Sobald die gewünschte Datenbank festgelegt wurde, kann der dazugehörende JDBC-Treiber als -Maven-Abhängigkeit herangezogen werden. - -Das folgende Beispiel zeigt eine Abhängigkeit zu einem MySql-Treiber: - -![dependency.png](./images/dependency.png) - -Die restlichen Schritte erfolgen im Java-Code. - -### Treiber laden/registrieren - -**Hinweis** -Dieser Schritt wird nur bei JDBC-Versionen benötigt, welche älter sind als die Version 4! -Bei neueren Versionen, werden alle Treiber geladen, welche auf dem Klassenpfad gefunden werden und -somit braucht es diesen Schritt nicht mehr. - -Mit der statischen Methode _forName_ von _Class_ wird die Klasse _Driver_ geladen. -Hier geht es um die Datenbank spezifischer Treiber, welche es der Anwendung den Datenzugriff auf der -gewünschten Datenbank ermöglicht. - -Im folgenden Beispiel wird der JDBC-Treiber für MySql registriert: - -![](./images/driver_registration.png) - -### Datenbankverbindung herstellen - -Der Zugriff auf einer Datenbank erfordert die Konfiguration folgender Elemente: - -- url: eine JDBC-URL, welche auf die gewünschte Datenquelle zeigt -- Benutzername: einer, für den Zugriff auf die Datenbank, autorisierter Benutzer -- Passwort: das Passwort des autorisierten Benutzers, womit er sich authentifizieren kann - -![](./images/connection_configuration.png) - -Die Konfiguration wird hier einfachheitshalber als Klartext im Code geschrieben. -Selbstverständlich dürfen vertrauliche Informationen wie z.B. das Passwort nicht als Klartext im Code stehen. -Für diesen Zweck, wie auch für die Konfiguration unterschiedlichen Umgebungen, eignen sich System- -oder Umgebungsvariablen (mit oder ohne Verschlüsselung) besser. - -Die obige Konfiguration kann nun für die Herstellung einer Datenbankverbindung verwendet werden. -Dazu wird die statische Methode _getConnection_ der Klasse _DriverManager_ verwendet: - -![](./images/connection_creation.png) - -Ab diesem Punkt repräsentiert das Connection-Objekt die Verbindung zur Datenbank. - -### SQL-Anweisung vorbereiten - -Die SQL-Anweisung kann als String vor der Ausführung vorbereitet werden: - -![](./images/select_query_no_params.png) - -Wenn eine IDE wie z.B. IntelliJ verwendet wird und eine Datasource mit der richtigen Datenbank definiert wird, -erkennt die IDE, dass es sich um eine SQL-Anweisung handelt und liefert entsprechend -Vorschläge und formatiert die Anweisung richtig und gut leserlich. - -Die obige SQL-Anweisung dient dazu alle Daten aus einer bestehenden Tabelle zu Lesen. -SQL-Anweisungen können aber auch Operationen wie Tabellen erstellen, Daten einfügen, löschen oder -bearbeiten usw. beinhalten. - -Als Beispiel, erstellt die folgende SQL-Anweisung eine Tabelle - falls diese noch nicht existiert - -mit ein paar gewünschten Attributen (Spalten): - -![](./images/create_table_query.png) - -### SQL-Anweisung ausführen - -Um SQL-Anweisungen ausführen zu können wird zunächst ein Statement-Objekt aus dem vorhandenen -Connection-Objekt erzeugt. Dieses Statement-Objekt wird verwendet, um die SQL-Anweisung an die -Datenbank zu richten. Dazu wird eine der _execute_ Methoden des Statement-Objektes verwendet. - -Im folgenden Beispiel wird die ein Statement-Objekt mithilfe des Connection-Objekt erstellt. -Danach wird die Methode _executeQuery_ verwendet, welche eine SQL-Anweisung als -Parameter entgegennimmt, diese ausführt und eine Referenz auf die Ergebnismenge (sog. ResultSet) zurückliefert: - -![](./images/statement_exectution.png) - -### Parametrisierte SQL-Anweisungen - -Bis jetzt haben wir SQL-Anweisungen ausgeführt, welche keine Einschränkungen beinhaltet haben. -Oft werden jedoch SQL-Anweisungen mit bestimmten Kriterien oder Einschränkungen benötigt damit die -zurückgelieferten Daten anhand dieser Kriterien gefiltert werden können. -In solchen Situationen wird der SQL "WHERE"-Befehl benutzt. Zum Beispiel: - -_SELECT \* FROM user WHERE username = 'gandalf' and age > 20;_ - -In diesem Beispiel, werden nur Einträge zurückgeliefert, welche die Kriterien _username = 'gandalf'_ -und _age > 20_ erfüllen. -Wenn nun dieselbe Anweisung mehrmals ausgeführt werden soll aber jeweils mit anderen Parameter (also mit unterschiedlichen _username_ und _age_), -wird die Anweisung mit Platzhaltern wie folgt geschrieben (ein Fragezeichen dient als einen Platzhalter): - -![](./images/query_with_placeholder.png) - -Für das eigentliche Ausführen der Anweisung müssen alle Platzhalter durch konkrete Werte ersetzt werden. -Dazu wird ein _PreparedStatement_ verwendet, welche es erlaubt, alle Platzhalter anhand ihrer Position (beginnend mit 1) -mittels _setXXX_ Methoden anzusprechen und mit den konkreten Werten zu ersetzen. -Anschliessend, kann auch hier eine der _executeXXX_ Methoden verwendet werden, um die Anweisung auszuführen: - -![](./images/prepared_statement.png) - -### Rückgabewerte verarbeiten - -Bei der Ausführung von bestimmten SQL-Anweisungen (z.B. bei SELECT Operationen), wird eine Ergebnismenge zurückgeliefert. -Ein ResultSet repräsentiert einen sog. _Cursor_ auf diese Ergebnismenge. -Die Methoden des ResultSets, bewegen den Cursor (je nach Art des Cursors) vorwärts, rückwärts, zur ersten oder zur letzten Position usw. -Somit kann über die gesamte Ergebnismenge, Zeile bei Zeile, iteriert werden, um die Werte zu lesen. - -![](./images/resultset_iteration.png) - -Im obigen Beispiel wird die _next_ Methode verwendet um den Cursor jeweils eine Zeile vorwärtszubewegen. -Aus jeder Zeile werden aus dem ResultSet mittels _getXXX_ Methoden (XXX steht für den Typ des Wertes) -die Werte, welche in dieser aktuellen Zeile vorhanden sind. -Die _getXXX_ Methoden, bekommen als Parameter entweder die Spaltenposition oder den Spaltennamen, welche gelesen werden soll. -Bei einer Spaltenposition hat die erste zurückgelieferte Spalte die Position 1. -Hinter der letzten Zeile liefert die _next_ Methode _false_ zurück und somit wird die Schleife beendet, -nachdem alle Zeilen bearbeitet worden sind. - -### Verbindungen schliessen - -Objekte der Typ _Connection_, _Statement_ oder auch _PreparedStatement_ sind sog. Ressourcen. -Solche Ressourcen müssen nach Verbrauch wieder explizit geschlossen werden: - -![](./images/close_statement_and_connection.png) - -Wenn diese Ressourcen innerhalb eines try-with-resources Befehls erstellt werden, entfällt diese -explizite Schliessung der Ressourcen. -Die Arbeit mit try-with-resources ist immer vorzuziehen, wenn es um Closable-Ressourcen geht. - -### Zusammenfassung - -Die folgende Beispiel-Methode fasst die oben erwähnten Arbeitsschritte mit JDBC (aktuelle Version) zusammen: - -```java -private static void findByUsernameAndAge(String url, String dbUsername, String password, String username, int age) throws SQLException { - try(Connection connection = DriverManager.getConnection(url, dbUsername, password)) { - String query = "SELECT * FROM user WHERE username = ? and age > ?"; - - try(PreparedStatement statement = connection.prepareStatement(query)){ - statement.setString(1, username); - statement.setInt(2, age); - - ResultSet resultSet = statement.executeQuery(); - - while(resultSet.next()){ - String data = resultSet.getInt(1) + ":" + resultSet.getString(2); - System.out.println(data); - } - } - } -} -``` - ---- - -![task1](/images/task.png) Jetzt bist du dran. Löse bitte diese [Aufgabe](../../../labs/02_java/11_java-jdbc/01_Jdbc_Exercises) in den Labs. +In diesem Modul wird der Aufbau und der Umgang mit Datenbanken behandelt. Aussserdem wird mit JDBC angeschaut wie die Verbindung zwischen Datenbank und einem Java Backend erstellt wird. +Datenbank und SQL Grundlagen (Datenbank 101, SQL Syntax und Constraints) werden vor der tatsächlichen Java Database Connection (JDBC) behandelt und dienen als Vorbereitung. +Das Datenbank-Design Kapitel enthält wichtige Informationen für künftige Arbeiten mit einer Datenbank, dies wird aber für die Labs nicht zwingend benötigt und ist deswegen optional. diff --git a/content/2025/docs/99_shared/database/_index.md b/content/2025/docs/99_shared/database/_index.md deleted file mode 100644 index 29a458f9e5..0000000000 --- a/content/2025/docs/99_shared/database/_index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Datenbanken" -weight: 10 -description: > - Grundlagen für die Verwendung von Datenbanken ---- - -## Inhalt - -In diesem Kapitel lernst du, wofür eine Datenbank ist und wie du sie benutzen kannst. Dir werden die Datentypen und -verschiedenen Statements näher gebracht, um diese später selbstständig verwenden zu können. Ziel ist auch, dass du -Datenbankdiagramme verstehen und erstellen kannst.