JDBC ist die Java-Schnittstelle für relationale Datenbanken. SQLite ist eine konkrete lokale Datenbank. PreparedStatement trennt SQL und Werte. Eine Transaktion verbindet mehrere Änderungen. PDF Batch Studio Desktop verwendet SQLite und Flyway für Projekte und Verlauf. Dieses Lernbeispiel zeigt zuerst JDBC ohne JavaFX, damit die Datenbankregel unabhängig von einer Oberfläche bleibt.
01Den SQLite-Treiber hinzufügen
Speichere pom.xml und Main.java in einem neuen Lernordner. Die SQLite-JDBC-Version stammt aus dem geprüften Desktop-Projekt. Der JDBC-URL jdbc:sqlite:demo.sqlite verwendet eine lokale Datei. Keine bestehende Produktdatenbank wird geöffnet.
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId><artifactId>learning</artifactId><version>1.0</version>
<properties><maven.compiler.release>21</maven.compiler.release><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
<dependencies><dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.53.4.0</version></dependency></dependencies>
<build><plugins>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.14.1</version></plugin>
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.5.3</version></plugin>
</plugins></build>
</project>
Starten / prüfen
mvn package dependency:copy-dependencies
java -cp "target/classes:target/dependency/*" tutorial.Main02Parametrisiert schreiben
Das CREATE TABLE beschreibt eine kleine Projekttabelle. Der INSERT besitzt Platzhalter. setString bindet Werte. ON CONFLICT aktualisiert denselben Lernschlüssel, sodass wiederholtes Ausführen keinen zweiten Datensatz erzeugt.
package tutorial;
import java.sql.DriverManager;
public class Main {
public static void main(String[] args) throws Exception {
try (var connection = DriverManager.getConnection("jdbc:sqlite:demo.sqlite")) {
try (var sql = connection.createStatement()) {
sql.execute("CREATE TABLE IF NOT EXISTS projects(id TEXT PRIMARY KEY, title TEXT NOT NULL)");
}
connection.setAutoCommit(false);
try (var insert = connection.prepareStatement("INSERT INTO projects VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET title=excluded.title")) {
insert.setString(1, "p1"); insert.setString(2, "Letters");
insert.executeUpdate(); connection.commit();
} catch (Exception error) {
connection.rollback(); throw error;
}
try (var query = connection.prepareStatement("SELECT title FROM projects WHERE id=?")) {
query.setString(1, "p1");
try (var rows = query.executeQuery()) {
if (rows.next()) System.out.println(rows.getString("title"));
}
}
}
}
}
03Commit und Rollback verstehen
setAutoCommit(false) beginnt die kontrollierte Transaktionsphase. commit bestätigt alle bisherigen Änderungen. rollback verwirft sie bei einem Fehler. try-with-resources schließt Verbindung und Statements.
04Von Erstellung zu Migration wechseln
CREATE TABLE IF NOT EXISTS verändert eine vorhandene Tabelle nicht. Flyway führt versionierte SQL-Dateien aus und merkt sich deren Stand. Die reale StudioRepository initialisiert diese Migrationen vor dem Zugriff. Eine neue Spalte braucht einen eigenen Migrationsschritt mit Prüfung bestehender Daten.
demo.sqlite bleibt erhalten. Der Datensatz p1 trägt den Titel Letters. Wiederholtes Ausführen erzeugt kein Duplikat.
Deine Übung
Füge zwei Datensätze in einer Transaktion ein und lasse den zweiten durch einen ungültigen Wert scheitern.
Lösung mit Erklärung anzeigen
Verwende unterschiedliche IDs und für den zweiten Titel null. NOT NULL lehnt ihn ab. Nach rollback darf auch der erste neue Datensatz nicht vorhanden sein. Prüfe das mit einer neu geöffneten Verbindung.
Projektbezug und Quellen
Das Beispiel ist zum Lernen vereinfacht. Die verlinkte Codeversion zeigt die Anwendung im Projekt und die dortigen Prüfungen.