For some reason there's no documentation on running liquibase inside Java code. I want to generate tables for Unit tests.
How would I run it directly in Java?
e.g.
Liquibase liquibase = new Liquibase()
liquibase.runUpdates() ?
In this article, we'll cover what you can do once you've created a database changelog file and you're ready to go: Embed Liquibase into your product. Embed Liquibase into your build tools. Run Liquibase to generate SQL for review.
If you install Liquibase manually, you must also install Java, which is available from Adoptium. If you use the Liquibase Installer, this version of Java is used during installation.
Liquibase offers a powerful open source database migration tool for Java apps. It brings structure and confidence to developers and DBAs that need to easily create and track database schema changes.
It should be something like (taken from liquibase.integration.spring.SpringLiquibase source):
java.sql.Connection c = YOUR_CONNECTION;
Liquibase liquibase = null;
try {
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c))
liquibase = new Liquibase(YOUR_CHANGELOG, new FileSystemResourceAccessor(), database);
liquibase.update();
} catch (SQLException e) {
throw new DatabaseException(e);
} finally {
if (c != null) {
try {
c.rollback();
c.close();
} catch (SQLException e) {
//nothing to do
}
}
}
There are multiple implementation of ResourceAccessor depending on how your changelog files should be found.
I found a way to achieve setting up the database using either maven or Java. The above example uses FileSystemResourceAccessor()
, which unfortunately makes it so that if you deploy an application which needs to set up a database from the jar itself, then you end up having to extract the jar as a zip as a workaround, since these liquibase files exist only in the jar. This means your jar ultimately isn't portable, and you have to have maven
wherever you want to set up the database.
Use this structure:
src/main/resources/liquibase/db.changelog-master.xml
src/main/resources/liquibase/changelogs/...
Your DB changelog master can look like this:
<?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"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<!-- <includeAll path="src/main/resources/liquibase/changelogs"/> -->
<include file="changelogs/my-date.1.sql" relativeToChangelogFile="true"/>
</databaseChangeLog>
You can use this section for your pom.xml
, in order to make sure mvn install
will also set up your liquibase DB.
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<changeLogFile>liquibase/db.changelog-master.xml</changeLogFile>
<driver>org.postgresql.Driver</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
</configuration>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
Use ClassLoaderResourceAccessor()
instead of FileSystemResourceAccessor()
.
public static void runLiquibase() {
Liquibase liquibase = null;
Connection c = null;
try {
c = DriverManager.getConnection(DataSources.PROPERTIES.getProperty("jdbc.url"),
DataSources.PROPERTIES.getProperty("jdbc.username"),
DataSources.PROPERTIES.getProperty("jdbc.password"));
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c));
log.info(DataSources.CHANGELOG_MASTER);
liquibase = new Liquibase(DataSources.CHANGELOG_MASTER, new ClassLoaderResourceAccessor(), database);
liquibase.update("main");
} catch (SQLException | LiquibaseException e) {
e.printStackTrace();
throw new NoSuchElementException(e.getMessage());
} finally {
if (c != null) {
try {
c.rollback();
c.close();
} catch (SQLException e) {
//nothing to do
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With