Liquibase in Java Anwendung einbinden

veröffentlicht am 24. September 2011

Heute habe ich mich mit dem leicht zu erlernenden Java Framework Liquibase beschäftigt. Liquibase basiert auf Datenbank unabhängigen Changesets im XML-Format und ermöglicht einfache und nachvollziehbare Änderungen an Datenbanken. Normalerweise führt man Liquibase mit Ant, Maven, Spring oder der Kommandozeile aus, ich wollte Liquibase jedoch zu Testzwecken direkt in meine Anwendung ohne Spring integrieren. Leider ist das API schlecht dokumentiert, sodass ich einige Stunden mit der Suche nach einer Lösung verbracht habe (dabei bin ich auf viele andere mit demselben Problem gestoßen).

Zunächst habe ich ein Maven-Projekt erstellt und den MySQL-Treiber sowie Liquibase eingebunden:

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.17</version>
</dependency>
<dependency>
	<groupId>org.liquibase</groupId>
	<artifactId>liquibase-core</artifactId>
	<version>2.0.1</version>
</dependency>

Danach habe ich zu Testzwecken ein sehr einfach gestricktes Changeset unter src/main/resources/changelog.xml angelegt:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
	http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
	<changeSet id="1" author="patrick">
		<createTable tableName="kontakt">
			<column name="id" type="int">
				<constraints primaryKey="true" nullable="false" />
			</column>
			<column name="vorname" type="varchar(32)">
				<constraints nullable="false" />
			</column>
			<column name="nachname" type="varchar(32)">
				<constraints nullable="false" />
			</column>
		</createTable>
	</changeSet>
</databaseChangeLog>

Zum Ausführen des Changesets habe ich dann folgende Klasse implementiert:

package de.techspread.liquibase;

import java.sql.Connection;
import java.sql.DriverManager;

import liquibase.Liquibase;
import liquibase.database.core.MySQLDatabase;
import liquibase.database.jvm.JdbcConnection;
import liquibase.resource.ClassLoaderResourceAccessor;

public final class Main {

	private String driver    = "com.mysql.jdbc.Driver";
	private String url       = "jdbc:mysql://localhost/liquibase";
	private String username  = "benutzername";
	private String password  = "passwort";
	private String changelog = "changelog.xml";			

	public static void main(String[] args) throws Exception {
		new Main();
	}

	public Main() throws Exception {
		Class.forName(driver);
		Connection connection = DriverManager.getConnection(url, username, password);
		JdbcConnection jdbcConnection = new JdbcConnection(connection);
		MySQLDatabase databaseConnection = new MySQLDatabase();
		databaseConnection.setConnection(jdbcConnection);
		Liquibase liquibase = new Liquibase(changelog, new ClassLoaderResourceAccessor(), databaseConnection);
		liquibase.update(null);
	}

}

Bevor man das Changeset ausführen kann, muss natürlich die Datenbank und ggf. einen entsprechender Benutzer eingerichtet werden.

Beim Start der Anwendung führt Liquibase nun die gewünschten Änderungen an der Datenbank durch (in diesem Fall wird eine Tabelle angelegt). Zusätzlich legt Liquibase eine eigene Tabelle an, in der sich Liquibase das aktuelle Changeset merkt.

Konfiguriert man nun weitere Changesets, bringt Liquibase die Datenbank beim nächsten Start der Anwendung auf den aktuellsten Stand. Damit gehören unnachvollziehbare Änderungen an der Datenbank der Vergangenheit an.

Sollte ein Datenbank-Update fehlschlagen, können zudem auch Rollback-Einträge definiert werden. Weiteres erfahrt ihr natürlich auf der Projektwebseite, ich möchte hier keine vollständige Dokumentation hinlegen ;)

Kommentare

Netter Post aber du hast bei der Methode Main() das void vergessen :)

Kommentar #1 von unwichtich am 06. Februar 2013


Hallo unwichtig,

das ist keine Methode, das ist der Konstruktor der Klasse, dementsprechend ist das „vergessene void“ ganz richtig :)

Die Ausführung des Changesets ist aber zugegebenerweise etwas Quick’n’Dirty, soll nur als einfaches Beispiel dienen.

Gruß
Patrick

Kommentar #2 von Patrick am 06. Februar 2013


Hinterlasse einen Kommentar