20 Einführung ins Datenbankmanagement mit JDBC
»Was kann gespeichert werden? Alles, was Sie gerne extrahieren möchten.«
– NSA-Präsentation zum System XKeyscore (2008)
Das Sammeln und Zugreifen auf und das Verwalten von Informationen ist im »Informationszeitalter« für die Wirtschaft eine der zentralen Säulen. Während früher Informationen auf Papier gebracht wurden, bietet die EDV hierfür Datenbanken. Sie werden von einem Datenbankmanagementsystem, kurz DBMS, verwaltet.
Ein Datenbankmodell bestimmt die Struktur, in der die Datenbasis, also Informationseinheiten, in Beziehung stehen und organisiert werden. Es gibt unterschiedliche Modelle, wobei das relationale Modell, das auf Tabellen basiert, am häufigsten vorkommt. Neben relationalen Datenbanken gibt es weitere Typen, wie dokumentenorientierte Datenbanken, Graphdatenbanken und Schlüssel-Werte-Datenbanken. Sie werden im Allgemeinen unter dem Begriff NoSQL-Datenbanken zusammengefasst. Für Java gibt es APIs für alle Arten von Datenbanken.
20.1 Relationale Datenbanken und Java-Zugriffe
Relationale Datenbanken gibt es seit den 1970er-Jahren. Die theoretischen Grundlagen wurden von Edgar F. Codd schon in den 1960er-Jahren gelegt.
20.1.1 Das relationale Modell
Die Grundlage für relationale Datenbanken sind Tabellen (auch Relationen genannt) mit ihren Spalten und Zeilen, die sogenannten Entitäten Eigenschaften zuweisen. In der Vertikalen sind die Spalten und in der Horizontalen die Zeilen angegeben. Eine Zeile (auch Tupel genannt) entspricht einem Eintrag einer Tabelle, eine Spalte (auch Attribut genannt) einem Element einer Tabelle.
Name | Adresse | Wohnort | |
---|---|---|---|
004 | Hoven G. H. | Sandweg 50 | Linz |
009 | Baumgarten R. | Tankstraße 23 | Hannover |
011 | Strauch GmbH | Beerenweg 34a | Linz |
013 | Spitzmann | Hintergarten 9 | Aalen |
… | … | … | … |
Jede Tabelle entspricht einer logischen Sicht des Benutzers. Die Zeilen einer Relation stellen die Datenbankausprägung dar, während das Datenbankschema die Struktur der Tabellen – also Anzahl, Name und Typ der Spalten – beschreibt.
Wenn wir nun auf diese Tabellen Zugriff erhalten wollen, um damit die Datenbankausprägung zu erfahren, benötigen wir Abfragemöglichkeiten.
20.1.2 Java-APIs zum Zugriff auf relationale Datenbanken
Steht auf der einen Seite das Datenbanksystem, so steht auf der anderen Seite unser Java-Programm und möchte auf die Daten zugreifen. Gewünscht ist eine einheitliche Programmierschnittstelle, sodass die Funktionen unterschiedlicher Datenbanken in gleicher Weise genutzt werden können.
Hier gibt es unterschiedliche APIs auf unterschiedlichen Ebenen. Auf der untersten Ebene stehen:
JDBC (inoffizielle Abkürzung für Java Database Connectivity)
R2DBC (Reactive Relational Database Connectivity)
JDBC und R2DBC abstrahieren von den relationalen Datenbanken durch eine API. Dadurch müssen Entwickler nicht verschiedene Zugriffsmethoden für die Datenbanken diverser Hersteller lernen. Java-Entwickler bekommen auf diese Weise Methoden an die Hand, die Verbindungen zu Datenbanken aufbauen, Datensätze lesen oder neue Datensätze verfassen. Zusätzlich können Tabellen aktualisiert und Prozeduren auf der Serverseite ausgeführt werden.
Aufbauend darauf gibt es abstraktere APIs wie JPA oder jOOQ, mit denen der Zugriff komfortabler und weniger fehleranfällig ist. R2DBS ist ein sehr neuer Standard, auf den wir nicht näher eingehen. Auch JPA wird hier nicht betrachtet.
20.1.3 Die JDBC-API und Implementierungen: JDBC-Treiber
JDBC bezeichnet einen Satz von Schnittstellen, mit denen man relationale Datenbanksysteme aus Java heraus ansprechen kann. Die API ist seit 20 Jahren Teil der Standard-API und die Typen verteilen sich auf die Pakete java.sql und javax.sql.
Um eine Datenbank über JDBC ansprechen zu können, müssen wir einen Treiber haben, der die JDBC-API implementiert und zwischen dem Java-Programm und der Datenbank vermittelt. Jeder Treiber ist üblicherweise anders implementiert, denn er muss die datenbankunabhängige JDBC-API auf die konkrete Datenbank übertragen. Jede Datenbank hat ihr eigenes Protokoll (und eventuell auch Netzwerkprotokoll), doch die Implementierung ist nur dem Datenbanktreiber bekannt.
JDBC bietet den Vorteil, dass der Zugriff auf die Datenbanken immer gleich aussieht, und jede relationale Datenbank von Java angesprochen werden kann. Nur ein entsprechender Treiber ist nötig. Die Hersteller von DBMS liefern in der Regel selbst einen JDBC-Treiber mit aus, den wir als JAR-Datei in den Modulpfad mit aufnehmen. Eine Suchmaschine hilft hier schnell weiter. Mit dem richtigen Treiber lassen sich selbst CSV-Dateien (siehe http://csvjdbc.sourceforge.net/) oder Excel (siehe https://sourceforge.net/projects/xlsql/) über JDBC ansprechen.
20.1.4 H2 ist das Werkzeug auf der Insel
Bevor wir mit Java eine Datenbank ansprechen können, steht die Inbetriebnahme des Datenbanksystems an (für dieses Kapitel ist das fast schon der schwierigste Teil). Nun gibt es eine große Anzahl von kommerziellen, freien und quelloffenen Datenbankmanagementsystemen, sodass sich dieses Tutorial der Einfachheit halber auf H2 beschränkt.
Die H2-Datenbank
Die Beispielabfrage aus Abschnitt 20.2 basiert auf H2 (http://www.h2database.com), da das DBMS so schön einfach ist und auch ohne Administratorrechte auskommt. H2 ist alleinstehend oder eingebettet lauffähig und verfügt über schöne Features. H2 hat eine Weboberfläche zur Konfiguration und für Abfragen und unterstützt alle wichtigen SQL-Eigenschaften wie Trigger und Joins sowie abgesicherte Verbindungen und die Volltextsuche. H2 hält außerdem den Speicherverbrauch klein. Außerdem lässt sich ein ODBC-Treiber (von PostgreSQL) nutzen, um H2 auch unter Windows-Programmen (etwa Access) als Datenbank zu nutzen.
Da JDBC von Datenbanken abstrahiert, ist der Java-Programmcode prinzipiell auf jeder Datenbank lauffähig und die Leser können gerne andere Datenbanken einsetzen.
Die H2-Datenbank und JDBC-Treiber
Bei H2 sind das Datenbankmanagementsystem und der Treiber zusammen in nur einem Java-Archiv gebündelt. Wir können also gut eine Dependency in unserer Maven-POM-Datei eintragen und H2 referenzieren:
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>