Start / Seminare / Quarkus Grundlagentraining
Modul
Datenzugriff
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Datenzugriff
0:00 Im ersten Modul hatten wir eine Anwendung, die zählen konnte. Jetzt bekommt sie ein Gedächtnis. Datenzugriff ist der Punkt, an dem aus einer Demo eine Anwendung wird — und zugleich der Punkt, an dem in vielen Projekten der meiste unnötige Code entsteht. Wir gehen diesen Weg in diesem Modul bewusst zweimal: einmal mühsam und einmal schlank.
0:20 Nicht, um Zeit zu verschwenden, sondern weil man den Gewinn nur schätzt, wenn man den Aufwand kennt. Ab hier begleitet uns außerdem eine durchgehende Fachlichkeit: die Werkbank, eine kleine Dienstleistungsbörse mit Leistungen, Kunden und Anbietern. Sie trägt uns bis zum letzten Modul.
Datenzugriff in Quarkus
0:37 Verschaffen wir uns zuerst einen Überblick: Welche Wege zu Daten gibt es in Quarkus überhaupt, und nach welcher Logik sind sie gebaut? Diese Frage lohnt sich, bevor man sich für einen entscheidet — denn die Auswahl ist größer, als die meisten Projekte nutzen, und die Entscheidung fällt man in aller Regel genau einmal. Was Sie hier am Anfang wählen, begleitet Sie durch die gesamte Lebensdauer der Anwendung. Also lohnt sich ein paar Minuten Überblick.
1:02 Quarkus geht hier denselben Weg wie überall: Es erfindet nichts Eigenes, sondern setzt auf den Standard. Für relationale Daten heißt der Jakarta Persistence — die Spezifikation, die früher unter dem Kürzel JPA lief — und die Umsetzung dahinter ist Hibernate, seit zwanzig Jahren die Referenz in der Java-Welt. Das ist eine gute Nachricht, denn Ihr Wissen bleibt gültig und Ihr Code bleibt portabel.
1:25 Neu ist etwas anderes: eine Schicht namens Panache, die den immer gleichen Standardkram wegnimmt. Sie ersetzt Hibernate nicht, sie legt sich davor. Und genau diesen Unterschied zwischen "es geht auch ohne" und "es geht deutlich angenehmer" führen wir gleich vor. Die Liste wirkt lang, aber das Prinzip dahinter ist eines. Für alles, wofür es einen Standard gibt, nutzt Quarkus den Standard — relational über Jakarta Persistence, Transaktionen über die übliche Annotation, Schema-Wandel über die etablierten Migrationswerkzeuge.
1:56 Wo es keinen Standard gibt, etwa bei den vielen NoSQL-Systemen, liefert Quarkus stattdessen den Client der jeweiligen Datenbank und macht ihn über Konfiguration zugänglich. Sie bekommen dort also keine ORM-Schicht, sondern einen gut integrierten Zugang. Der praktische Nutzen dieser Aufstellung liegt weniger im Auswendiglernen als in der Beruhigung: Was immer Sie an Datenhaltung mitbringen, es gibt einen vorgezeichneten Weg dorthin.
2:21 Warum lohnt sich der Standard-Weg? Weil er Sie unabhängig hält. Ein Wechsel der Datenbank oder auch nur ein Upgrade wird zur Konfigurationsfrage statt zur Umbauaktion. Panache greift das an einer anderen Stelle an: Es nimmt Ihnen den Code ab, den Sie in jeder Anwendung neu schreiben würden und der in keiner interessant ist.
2:39 Und die Migrationswerkzeuge sorgen dafür, dass Ihr Datenbankschema dieselbe Versionsgeschichte hat wie Ihr Code — ein Punkt, der unterschätzt wird, bis das erste Mal jemand fragt, welche Spalten auf dem Testsystem eigentlich existieren. Transaktionen schließlich sind eine Annotation. Das klingt banal, ist aber der Unterschied zwischen sauberen Grenzen und Zufall.
Dev Services
3:00 Bevor wir Daten lesen können, brauchen wir eine Datenbank. Das ist normalerweise der Punkt, an dem ein Seminar ins Stocken gerät: Jeder installiert, jeder hat eine andere Version, bei zweien läuft schon etwas auf dem Port. Genau diesen Nachmittag nimmt uns Quarkus ab, und zwar auf eine Art, die man beim ersten Mal kaum glaubt.
3:18 Das ist die Bequemlichkeit, die ich im ersten Modul schon angedeutet habe — und einer der stärksten Gründe, sich das Framework überhaupt anzusehen. Die klassische Ansage zum Projektstart lautet: "Installier dir erst mal Postgres, leg die Datenbank an, spiel das Schema ein, dann melde dich wieder." Ein halber Tag, für jeden im Team, und danach hat trotzdem jeder eine leicht andere Umgebung.
3:42 Quarkus dreht das um. Sobald eine Datenbank-Erweiterung im Projekt liegt und Sie keine Verbindung konfiguriert haben, startet das Framework die Datenbank selbst — in einem Container, im Hintergrund, beim Anwendungsstart. Sie sagen nur noch, welche Art von Datenbank Sie wollen. Adresse, Benutzer, Passwort vergibt Quarkus.
4:01 Das ist keine Spielerei, sondern der Punkt, an dem Onboarding von einem halben Tag auf einen Befehl schrumpft. Der offensichtliche Gewinn ist Zeit. Der wichtigere ist Gleichheit: Alle im Team arbeiten gegen dieselbe Datenbank in derselben Version, und niemand hat noch eine alte Installation von vor drei Jahren im Hintergrund laufen.
4:21 Das Prinzip gilt übrigens nicht nur für Datenbanken — Kafka, AMQP und RabbitMQ funktionieren genauso, wie wir in Modul fünf sehen werden. Und es hat einen Nebeneffekt, den man erst später zu schätzen weiß: Automatisierte Tests laufen damit gegen eine echte Datenbank statt gegen einen In-Memory-Ersatz, der sich in Details anders verhält.
4:40 Wer schon einmal einen Fehler gejagt hat, der nur in Produktion auftrat, weiß, was das wert ist. Die häufigste Überraschung ist zugleich die logischste: Sobald irgendwo eine Verbindungsadresse steht, schaltet sich der Dev Service ab. Das ist richtig so — er soll ja nicht Ihre echte Datenbank überschreiben —, aber es passiert oft versehentlich, wenn ein Wert aus einem alten Projekt mitwandert.
5:03 Deshalb gehört die Produktionsadresse ins entsprechende Profil und nicht in die allgemeine Konfiguration. Zweitens: Ohne laufende Container-Runtime bricht der Start ab, mit einer klaren Meldung immerhin. Und drittens, ganz wichtig für die Erwartungshaltung: Der Container ist flüchtig. Ihre Testdaten sind nach dem Neustart weg. Das ist gewollt — wer sie behalten will, braucht eine echte Instanz.
Datenzugriff umsetzen
5:27 Jetzt schreiben wir Code, der Daten liest — und zwar absichtlich erst einmal auf dem umständlichen Weg. Das ist kein Zeitvertreib. Sie werden gleich eine Klasse sehen, die für eine einzige triviale Aufgabe erstaunlich viel Aufwand treibt, und genau dieses Gefühl brauchen wir. Denn den Wert einer Abkürzung erkennt nur, wer den langen Weg einmal gegangen ist. Danach zeigen wir dieselbe Aufgabe noch einmal, und der Unterschied wird für sich sprechen.
5:52 Fünf Schritte, und drei davon sind reine Formalität. Zwei Erweiterungen ins Projekt, eine Zeile Konfiguration für die Art der Datenbank, die Strategie für das Schema festlegen. Erst dann wird es fachlich: Sie beschreiben mit einer Klasse, wie eine Leistung aussieht, und bauen anschließend die Klasse, die diese Leistungen aus der Datenbank holt.
6:12 Beachten Sie, was hier nicht mehr vorkommt: kein Startskript, kein Port, kein Passwort. Für die Produktion sieht das anders aus, dort steht eine echte Adresse im entsprechenden Profil — aber eben nur dort, und nicht im Weg, während Sie entwickeln. Worauf es hier ankommt, ist weniger das, was dasteht, als das, was fehlt: keine Adresse, kein Benutzer, kein Passwort.
6:34 Genau diese Lücke ist das Signal für Quarkus, die Datenbank selbst zu starten. Die zweite Zeile bestimmt, was mit dem Schema passiert — hier legt Hibernate die Tabellen bei jedem Start neu an und spielt anschließend Testdaten ein. Für die Entwicklung ist das ideal, für Produktion natürlich undenkbar, deshalb steht dort eine andere Strategie im Profil.
6:55 Ein Hinweis für alle, die ältere Anleitungen lesen: Dieser Schlüssel hieß früher anders. Wenn Sie im Netz noch "database.generation" finden, ist das nicht falsch gedacht, nur veraltet. Was Sie hier sehen, ist eine ganz normale Java-Klasse mit ein paar Annotationen. Mehr braucht es nicht, damit Hibernate weiß, welche Tabelle gemeint ist und welches Feld der Schlüssel.
7:17 Der interessante Punkt ist die Richtung: Wir beschreiben nicht die Datenbank, wir beschreiben unsere Fachlichkeit — eine Leistung hat eine Bezeichnung und einen Preis. Die Tabelle entsteht daraus. Für den Preis nehmen wir bewusst einen Dezimaltyp und keine Fließkommazahl. Wer schon einmal erlebt hat, wie sich Rundungsfehler durch eine Rechnung fressen, macht diesen Fehler genau einmal.
7:39 Und hier ist der Punkt, auf den ich hinauswollte. Diese Klasse tut genau eines: Sie holt alle Leistungen. Dafür braucht es eine injizierte Hilfsklasse, eine Abfragesprache, die dem SQL ähnelt, aber nicht SQL ist, und eine Typangabe. Für diese eine banale Aufgabe ist das erstaunlich viel Aufwand. Und jetzt stellen Sie sich vor, Sie bräuchten auch noch Speichern, Löschen, Zählen, Suchen nach dem Schlüssel — jedes Mal ähnlicher, mühsamer Code, und das für jede weitere Entität.
8:09 Diese Klasse ist nicht falsch. Sie ist nur unnötig. Genau an diesem Punkt setzt Panache an.
Panache
8:16 Schauen wir uns also an, wie derselbe Zugriff aussieht, wenn man den immer gleichen Standardcode wegnimmt. Panache ist kein zweites Framework, das Sie zusätzlich lernen müssten, und es ersetzt Hibernate auch nicht — es legt sich davor und nimmt Ihnen ab, was in jeder Anwendung gleich aussieht. Der Umstieg kostet eine geänderte Zeile in der Projektdatei. Was Sie dafür bekommen, sehen Sie am besten im direkten Vergleich mit der Klasse von eben.
8:41 Panache beruht auf einer schlichten Beobachtung: Datenzugriffs-Klassen unterscheiden sich in aller Regel nur darin, für welche Entität sie zuständig sind. Alles andere — alle holen, eine über den Schlüssel finden, speichern, zählen — ist immer dasselbe. Also schreibt man es einmal und vererbt es. Sie geben Ihrer Klasse eine Schnittstelle mit, nennen dabei die Entität, und bekommen die Standardmethoden geschenkt.
9:05 Was bleibt, ist genau das, was an Ihrer Fachlichkeit besonders ist. Das ist kein neues Framework und keine Magie, sondern eine Abkürzung für den immer gleichen Weg — mit allem darunter, was Sie von Hibernate kennen. Der Wechsel kostet Sie eine geänderte Abhängigkeit, mehr nicht. Was Sie dafür bekommen, sehen Sie am besten am Vergleich mit der Folie von eben: Die Hilfsklasse verschwindet, die Abfragesprache verschwindet, und Methoden, die Sie nie geschrieben haben, sind trotzdem da.
9:33 Wichtig ist die andere Richtung: Sie verlieren nichts. Wo eine Abfrage tatsächlich anspruchsvoll wird, schreiben Sie sie weiterhin selbst — Panache nimmt Ihnen die Standardfälle ab, nicht die Kontrolle. Genau das ist der Unterschied zwischen einer Abkürzung und einer Zwangsjacke. Die Klasse ist leer. Das ist die ganze Pointe.
9:51 Alles, was auf der vorigen Code-Folie noch Arbeit war, steckt in der Schnittstelle, und die Angabe der Entität sagt Panache, worauf sich das beziehen soll. Sie können ab sofort alle Datensätze holen, einen über seinen Schlüssel finden, speichern und zählen — ohne eine Zeile dafür geschrieben zu haben. Wenn Sie später eine eigene Suche brauchen, kommt sie einfach in diese Klasse dazu und steht neben dem Geerbten.
10:14 Das ist der Normalfall, und genau so werden wir es in der nächsten Aufgabe machen. Jetzt übertragen Sie das Muster. Zwei weitere Entitäten, zwei Repositories, und diesmal mit eigenen Suchmethoden — nach der Mailadresse und nach dem Namen. Das Ziel ist nicht, dass Sie tippen können, sondern dass Sie den Übergang spüren: Standardfälle geschenkt, Besonderes selbst formuliert.
10:37 Wer Lust auf mehr hat, macht die Namenssuche unabhängig von Groß- und Kleinschreibung. Das klingt nach einer Kleinigkeit und ist doch die häufigste Beschwerde echter Anwender — "ich finde den Eintrag nicht", weil irgendwo ein großer Buchstabe stand. Wie das geht, sehen Sie gleich; probieren Sie es vorher selbst. Drei Fallen, die alle drei still zuschlagen.
10:58 Die erste: Wenn Sie das erste Ergebnis nehmen, ohne dass die Spalte eindeutig ist, bekommen Sie irgendeinen Treffer — und merken es nicht, solange die Testdaten brav sind. Die zweite betrifft die Groß- und Kleinschreibung: Sie müssen beide Seiten des Vergleichs anfassen. Wer nur die Datenbankspalte kleinschreibt, den Suchbegriff aber nicht, hat sich die Arbeit gemacht und trotzdem nichts gewonnen.
11:21 Und die dritte ist ein Klassiker beim Umstieg: In der Abfrage steht der Name des Java-Feldes, nicht der Name der Datenbankspalte. Sie beschreiben Ihre Objekte, nicht Ihre Tabellen. Zwei Zeilen je Suche, und beide zeigen dasselbe Muster: Sie beschreiben nur noch die Bedingung, alles andere ist geerbt. Bei der zweiten Methode sehen Sie die Lösung für das Groß- und Kleinschreibungsproblem — beide Seiten werden kleingeschrieben, dann kann der Vergleich nicht mehr scheitern.
11:48 Halten wir fest, was Sie aus diesem Modul mitnehmen: Die Infrastruktur besorgt sich Quarkus selbst, die Standardzugriffe schenkt Ihnen Panache, und Ihr Code beschreibt nur noch das, was an Ihrer Fachlichkeit besonders ist. Im nächsten Modul öffnen wir diese Daten nach außen — als REST-Schnittstelle.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →