Wie lässt sich in Java eine eingebettete Datenbank realisieren?
Die gesamte Routine wird von einem try-catch-Block
umschlossen, um SQL-Exceptions abzufangen.
Als
erstes muss der Treiber geladen werden:
Class.forName("org.h2.Driver");
Hierzu ist es notwendig, die jeweils aktuelle Jar-Datei
unter http://www.h2database.com/html/download.html
herunterzuladen und in den Classpath einzubinden1. Vergessen Sie auch
nicht, bei Verwendung von Eclipse die Datei in den
Build-Path aufzunehmen. (Project-Properties → Java
Build Path).
Der nächste Schritt besteht
darin, eine Verbindung zur Datenbank aufzubauen. Dies
geschieht durch die statische Methode DriverManager.getConnection().
Sie erwartet drei Parameter
- den URL zur Datenbankdatei
- den Nutzernamen
- das Zugangs-Passwort
Der Datenbank-URL muss in der Form jdbc:h2:<PfadZurDatei>
angegeben werden, wobei der Pfad relativ oder absolut
angegeben werden kann. Ist keine Datenbank-Datei
angelegt, so wird sie gebildet. Im Beispiel befindet sie
sich im versteckten Verzeichnis <UserHome>/.javabeginners
und trägt den Namen h2Test.h2.db. Die
Dateiendung h2.db darf nicht mit angegeben
werden. Wird kein Pfad angegeben, so wird das aktuelle
Arbeitsverzeichnis als Speicherort verwendet.
Nutzername und Passwort sind optional und können
leer bleiben, bzw. selbstverständlich wie auch der
Datenbankname über eine Benutzeroberfläche
dynamisch zur Laufzeit eingegeben werden. Auf diese
Weise könnten z.B. individuelle
Programm-Einstellungen gespeichert werden.
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class H2Class {
public static void main(String[] a) throws Exception {
Class.forName("org.h2.Driver");
readDB();
}
public static void readDB() {
String tab = "TESTTABELLE";
try (Connection conn = DriverManager.getConnection("jdbc:h2:~/.javabeginners/h2Test", "", "")) {
DatabaseMetaData md = conn.getMetaData();
String[] types = { "TABLE", "SYSTEM TABLE" };
ResultSet metaRS = md.getTables(null, null, "%", null);
while (metaRS.next()) {
String tableCatalog = metaRS.getString(1);
System.out.println("Catalog: " + tableCatalog);
String tableSchema = metaRS.getString(2);
System.out.println("Tabellen-Schema: " + tableSchema);
String tableName = metaRS.getString(3);
System.out.println("Tabellen-Name: " + tableName);
String tableType = metaRS.getString(4);
System.out.println("Tabellen-Typ: " + tableType + "\n");
}
Statement stmt = conn.createStatement();
String dropQ = "DROP TABLE IF EXISTS " + tab;
stmt.executeUpdate(dropQ);
String createQ = "CREATE TABLE IF NOT EXISTS " + tab
+ "(ID INT PRIMARY KEY AUTO_INCREMENT(1,1) NOT NULL, NAME VARCHAR(255))";
stmt.executeUpdate(createQ);
String insertQ = "INSERT INTO " + tab + " VALUES(TRANSACTION_ID(),'Hello World!')";
stmt.executeUpdate(insertQ);
ResultSet selectRS = stmt.executeQuery("SELECT * FROM " + tab);
while (selectRS.next()) {
System.out.printf("%s, %s\n", selectRS.getString(1), selectRS.getString(2));
}
System.out.println("Liste Tabellen...");
String tablesQ = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='PUBLIC'";
ResultSet tablesRS = stmt.executeQuery(tablesQ);
while (tablesRS.next()) {
System.out.printf("Tabelle %s vorhanden \n", tablesRS.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Tabellen-Metadaten auslesen
Über das Connection-Objekt werden mit Hilfe der
Methode getMetaData() die Meta-Daten der
Datenbank abgerufen. Sie müssen nun nach den
gewünschten Typen gefiltert werden. Dies geschieht
durch die Übergabe eines String-Arrays, in das
diese eingetragen werden, an die Methode getTables()
des DatabaseMetaData-Objektes. Im Beispiel werden die
Metadaten der System-Tabellen und der vom Nutzer
angelegten Tabellen abgefragt. Möchte man nur die
Ausgaben für die Nutzertabellen abfragen, so
entfernt man den Eintrag SYSTEM TABLE aus dem Array.
Neben
den genannten können hier auch die folgenden Typen
gewählt werden:
- "VIEW"
- "GLOBAL TEMPORARY"
- "LOCAL TEMPORARY"
- "ALIAS"
- "SYNONYM"
Die anderen drei Parameter, catalog, schemaPattern
und tableNamePattern, können verwendet
werden, um die Suche weiter einzuschränken. Die
Angabe null für die ersten beiden
Parameter bewirkt, dass diese Einschränkungen nicht
verwendet werden. Das Prozentzeichen % des
dritten Parameters bewirkt das Auslesen aller
eingetragenen Tabellen.
In der Folge wird über
das ResultSet iteriert, um die Einträge
auszugeben.
Abfragen und Updates
Das Interface java.sql.Statement liefert ein Objekt zum Absetzen von Datenbank-Anfragen und zur Ausgabe der entsprechenden Ergebnisse. Im Beispiel werden auf ihm zwei verschiedene Methoden aufgerufen:
- executeUpdate() liefert einen int-Wert und wird für INSERT-, UPDATE- und DELETE-Statements verwendet. Der Statement-String wird als Parameter übergeben.
- executeQuery() liefert ein ResultSet und wird üblicherweise für SELECT-Abfragen eingesetzt.
Die Tabelle mit dem in der Variablen tab gespeicherten Namen wird im Folgenden der Reihe nach
- gelöscht, falls sie bereits existiert
- neu erzeugt, falls sie noch nicht existieren sollte
Hier fällt die SQL-Funktion AUTO_INCREMENT(1,1) auf. Die Parameter geben an, dass die automatische Incrementierung des ID-Wertes bei 1 beginnen und in Einer-Schritten erfolgen soll. - mit einem neuen Eintrag versehen
Hier ist zu beachten, dass der Auto-Increment-Wert der ID nicht, wie etwa bei MySQL, selbstständig erzeugt und incrementiert wird, sondern, dass hierfür die Funktion TRANSACTION_ID() eingetragen werden muss. - ausgelesen
Den Abschluss bildet eine weitere Form der Ermittlung der existierenden User-Tabellen: Auch hier stellt eine SELECT-Abfrage die Grundlage dar, um ein ResultSet zu erhalten, das durchlaufen und ausgegeben werden kann. Mit conn.close() wird die Verbindung zur Datenbank schließlich geschlossen.
1) Verwendete Version: 1.3.160 | Es muss beachtet werden, dass bei Einbindung einer anderen Version, der vorliegende Quelltext möglicherweise nicht mehr fehlerfrei lauffähig ist!
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.