Using Liquibase with Spring Boot

Image of Julius Krah Written by: Julius Krah

The purpose of this tutorial is to guide you through the process of using Liquibase as part of your Spring Boot workflow. Spring Boot makes it easy to create standalone, production grade Spring-based Applications that just works.

Uses

You can use Spring Boot to create Java applications that can be started by using java -jar or more traditional war deployments.

With Spring Boot some of the heavy lifting of configuring beans to setup things like messaging, database connection, migration, etc. are already done for you and what you need to do is add the correct jar file on the classpath to be picked up by the framework for auto configuration.

Some Spring Boot features include Profiles, Logging, Security, Caching, Spring Integration, Testing, and more.

Prerequisites

To be able to follow along with this tutorial, you need a Java Development Kit (JDK 14+).

Tutorial

We will be working with a Gradle project. To create the project, head over to the Spring Initializer website.

  1. Under Project select Gradle Project.
  2. Select Java as your Language.
  3. Under Spring Boot, select 2.3.4.
  4. For Packaging, select Jar.
  5. Java = 11.

After picking your options, your selection should look similar to the screenshot below:

Click on generate to download your project template as a zip file. Next, extract it and open in your favorite IDE.

Note: Liquibase supports a variety of Commands. At the time of this article, Spring Boot only integrates the update, futureRollbackSQL, dropAll, updateTestingRollback, and clearChecksums commands.

Spring Boot offers a subset of the Liquibase configuration options. In the table below, you can see the Spring Boot options listed against the Liquibase options.

Spring Boot Liquibase Description
spring.liquibase.change-log changeLogFile changelog configuration path
spring.liquibase.labels labels Comma-separated list of runtime labels to use
spring.liquibase.contexts Contexts Comma-separated list of runtime contexts to use
spring.liquibase.database-change-log-lock-table databaseChangeLogLockTableName Name of table to use for tracking concurrent Liquibase usage
spring.liquibase.database-change-log-table databaseChangeLogTableName Name of table to use for tracking change history
spring.liquibase.default-schema defaultSchemaName Default database schema
spring.liquibase.liquibase-schema liquibaseSchemaName Schema to use for Liquibase objects
spring.liquibase.liquibase-tablespace databaseChangeLogTablespaceName Tablespace to use for Liquibase objects
spring.liquibase.parameters.* parameter.* changelog parameters
spring.liquibase.password password Login password of the database to migrate
spring.liquibase.tag   Tag name to use when applying database changes. Can also be used with rollbackFile to generate a rollback script for all existing changes associated with that tag
spring.liquibase.url url JDBC URL of the database to migrate. If not set, the primary configured data source is used
spring.liquibase.user username Login user of the database to migrate

Now we tell Spring Boot how to run the Liquibase migrations. We will make the changes in src/main/resources/application.properties. Add the following values (modify to fit your database requirements):

spring.datasource.url=jdbc:h2:~/liquibase;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml

The final step is to create the changelog file src/main/resources/db/changelog/db.changelog-master.xml

<?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:pro="http://www.liquibase.org/xml/ns/pro" 
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-3.8.xsd">
	<changeSet id="202010211812" author="Julius Krah">
		<createTable tableName="house">
			<column name="id" type="bigint">
				<constraints primaryKey="true" primaryKeyName="house_id_pk" />
			</column>
			<column name="owner" type="varchar(250)">
				<constraints unique="true" uniqueConstraintName="house_owner_unq" />
			</column>
			<column name="fully_paid" type="boolean" defaultValueBoolean="false"></column>
		</createTable>
		<createTable tableName="item">
			<column name="id" type="bigint">
				<constraints primaryKey="true" primaryKeyName="item_id_pk" />
			</column>
			<column name="name" type="varchar(250)" />
			<column name="house_id" type="bigint">
				<constraints nullable="false" notNullConstraintName="item_house_id_nn" />
			</column>
		</createTable>
		<addAutoIncrement tableName="house" columnName="id" columnDataType="bigint" startWith="1" incrementBy="1" />
		<addAutoIncrement tableName="item" columnName="id" columnDataType="bigint" startWith="1" incrementBy="1" />
		<createSequence sequenceName="hibernate_sequence" incrementBy="1" startValue="1" />
		<addForeignKeyConstraint baseTableName="item" baseColumnNames="house_id" constraintName="item_house_id_fk" referencedTableName="house" referencedColumnNames="id" />
	</changeSet>
</databaseChangeLog>

When you have completed these steps, you can run your migration with the following command: ./gradlew bootRun

Source code is available at: https://github.com/juliuskrah/spring-boot-liquibase

See also