Overview
Als Alternative zu externen MySQL-Datenbanken gibt es für Java eine Reihe sogenannter eingebetteter Datenbankensysteme. Eine eingebettete Datenbank ist eine Datenbank, die ohne Server funktioniert und vollständig in der Java-Anwendung integriert ist.
Eine eingebettete Datenbank ist eine Datenbank, die ohne Server funktioniert. Sie ist vollständig in der Anwendungssoftware eingebettet und tritt nach außen nicht in Erscheinung. Ein Zugriff auf die eingebettete Datenbank ist deshalb von außerhalb erst einmal nicht möglich.
In unseren Kapiteln zu Java und MySQL hatten wir es mit externen Datenbanken zu tun. Diese liefen unabhängig von unserem Java-Programm standalone.
Die Infografik unten zeigt den prinzipiellen Unterschied zwischen einer eingebetteten Datenbank und einer externen Datenbank:
Es gibt unterschiedliche Datenbanksysteme, die direkt in unserer Java-Programm eingebettet werden können. Zum Beispiel:
Wir entscheiden uns in diesem Tutorial für die H2 Datenbank. Sie ist besonders flott einzurichten und hat noch folgende Vorteile:
Also, los gehts 🤠
Die Installation der H2 Datenbank in unserem Java-Projekt ist sehr einfach.
Lade dir zunächst die jar-Datei für das H2 Datenbanksystem herunter. Auf der offiziellen Seite von H2 kannst du dir im Download-Bereich eine Platform-Independent Zip der neuesten Version runterladen. In dieser zip-Datei befindet sich im bin-Ordner die jar-Datei (z.B. h2-1.4.200.jar) - und genau diese eine Bibliotheks-Datei brauchen wir.
Als nächsten bindest du die jar in dein Java-Projekt ein:
Die Kommunikation mit der H2 Datenbank erfolgt mittels der JDBC. Hierzu müssen wir zuerst den JDBC Datenbanktreiber für das H2 System laden:
Class.forName("org.h2.Driver");
Die Verbindung zur Datenbank wird durch die Connection-Instanz repräsentiert. Wir erhalten diese, indem wir die statischen getConnection()-Methode aufrufen.
Connection con = DriverManager.getConnection("jdbc:h2:file:~/data/test", "user","");
getConnection hat drei String-Parameter: Die JDBC-Url, den Datenbanknutzer ("user") und ein Datenbankpasswort (leer).
Die JDBC-URL ist in unserem Beispiel jdbc:h2:file:~/data/test. Bei Unix/ Linux basierten Betriebssystemen bedeutet das, dass die eingebettete Datenbank namens test im Home Verzeichnis des Nutzers im Ordner data lokal gespeichert wird.
In Windows müsste die JDBC-URL so aussehen: jdbc:h2:file:C:/data/test.
Wir können unserer H2 Datenbank vollständig mit Standard-SQL verwalten. Die uns bekannten JDBC-Klassen und -Interfaces machen die Kommunikation zwischen Java und der Datenbank möglich.
Mit folgendem Code verbinden wir zur H2 Datenbank, erstellen eine Tabelle, fügen einen Datensatz ein und lesen ihn dann einmal aus:
package p1;
import java.sql.*;
public class DBTest {
public static void main(String[] args){
try {
//Treiber laden und verbinden
Class.forName("org.h2.Driver");
Connection con = DriverManager.getConnection("jdbc:h2:file:~/data/test", "user","");
// Statement Objekt erstellen
Statement stm = con.createStatement();
// Tabelle erstellen
String sql_create = "CREATE TABLE IF NOT EXISTS kunden(id INTEGER, name VARCHAR(50), vip BOOLEAN);";
stm.execute(sql_create);
// Datensatz einfügen
String sql_insert = "INSERT INTO kunden(id, name, vip) VALUES(1, 'Elon Musk', TRUE)";
stm.execute(sql_insert);
// Datensatz auslesen
String sql_select = "SELECT * FROM kunden";
ResultSet rs = stm.executeQuery(sql_select);
while(rs.next()){
System.out.println(rs.getString(1) + " " +
rs.getString(2) + " " +
rs.getString(3));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Das H2 Datenbanksystem ist sehr flexibel und ermöglicht mehrere unterschiedliche Verbindungsmodi. Diese werden einfach über eine Anpassung der Datenbank-URL eingestellt. Im Folgenden schauen wir uns zwei unterschiedliche Modi genauer an:
Eine vollständige Liste aller Verbindungsarten kannst du auf der offiziellen Website von H2 nachlesen.
Im bisherigen Beispiel wurde unsere Datenbank lokal in einer Datei gespeichert. Die Daten sind damit persistent, d.h. dauerhaft verfügbar.
Es ist aber nicht immer ideal, Datenbanken persistent zu halten. In einigen Fällen empfielt es sich nämlich, sie stattdessen in den Arbeitsspeicher zu laden. Solche Datenbanken werden in-memory Datenbanken genannt.
Was sind die Vorteile? Das Laden in den Arbeitsspeicher ermöglicht deutlich höhere Zugriffsgeschwindigkeiten und bessere Performance. Allerdings werden die Daten beim Schließen des Programms gelöscht. Hier einige Beispiele, wo in-memory Datenbanken zum Einsatz kommen:
Das H2 Datenbanksystem unterstützt einen in-memory-Modus für solche Zwecke. Eine in-memory Datenbank kann über folgende Modus-Anpassung in der JBDC-URL erstellt werden: jdbc:h2:mem:datenbank_name
Hier ein Beispiel:
DriverManager.getConnection("jdbc:h2:mem:test2", "user",""); // in-memory-Datenbank
Die "temporäre" Datenbank namens test2 hat eine Lebensdauer, die der Laufzeit des Programms entspricht. Sie endet also mit dem Ende des Programms.
Im eingebetteten ("=serverlosen") Modus kann immer nur ein einziger Zugriff auf die Datenbank erfolgen. Häufig muss ein Zugriff auf eine Datenbank aber von mehreren Personen aus einem Netzwerk oder von verschiedenen virtuellen Maschinen erfolgen. Praktischerweise gibt es einen sog. Mixed Mode, der uns einen H2-Server starten lässt (und das ganz automatisch).
Der Mixed Mode ist eine Kombination aus dem eingebetteten Modus und einem Server-Modus. Das erste Programm startet die Datenbank im eingebetteten Modus, eröffnet gleichzeitig aber auch einen Server, mit dessen Hilfe andere Anwendungen auf die Datenbank zugreifen können. Die multiple Nutzung ein und derselben Datenbank wird möglich.
Am einfachsten erreichen wir das, indem wir ;AUTO_SERVER=TRUE an die Datenbank-URL anhängen:
// Application 1:
DriverManager.getConnection("jdbc:h2:file:~/data/test;AUTO_SERVER=TRUE");
// Application 2:
DriverManager.getConnection("jdbc:h2:file:~/data/test;AUTO_SERVER=TRUE");
Beim Einsatz dieser Verbindung nutzt der Server standardmäßig irgendeinen freien TCP Port. Der Port kann aber auch manuell umgestellt werden, z.B. AUTO_SERVER_PORT=9090.
Java Basics
[Java einrichten] [Variablen] [Primitive Datentypen] [Operatoren] [if else] [switch-case] [Arrays] [Schleifen]
Objektorientierung
[Einstieg] [Variablen ] [Konstruktor] [Methoden] [Rekursion] [Statische Member] [Initializer] [Pass-by-value] [Objektsammlungen] [Objektinteraktion] [Objekte löschen]
Klassenbibliothek
[Allgemeines] [String ] [Math] [Wrapper] [Scanner] [java.util.Arrays] [Date-Time-API]
Vererbung
[Einstieg Vererbung] [Konstruktoren bei Vererbung ] [Der protected Zugriffsmodifikator] [Abstrakte Klassen und Methoden] [Polymorphie in Java] [Typumwandlung] [Die Klasse Object] [Die toString()-Methode] [Objekte vergleichen] [Was ist ein Interface?]