Evolving your database in a Spring Boot Application with Liquibase

Elie Daher
4 min readMay 16, 2021

--

Liquibase enables you to go faster and automate your processes by tracking, versioning and deploying database changes.

Why do you need Liquibase ?

  • Deploying/rollbacking database changes seemingly and easy integration with your CD pipeline
  • Creating a new environment/sql schema by only running a command
  • Versioning changes and migration in your database
  • Auditing database changes

How does it works ?

Liquibase uses a table databasechangelog to track all the changes, which will be created the first time Liquibase runs.

Each change/migration will be audited in a table, and information such as id, author, filename and many more will be stored.

databasechangelog table

Another table called databasechangeloglock is created, which will ensure that only one instance of Liquibase is running at a time so that no conflict will happen during the migration.

databasechangeloglock table

How to set it up ?

Add the following dependencies

<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
</dependency>

Add the following plugin

<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<configuration>
<propertyFile>${liquibase.propertyFile}</propertyFile>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
</configuration>
</plugin>
Example of property file location

liquibase.properties file contains

  • database information such as url , username , password , driver
  • changelog file location

Here is an example of a liquibase.properties file

liquibase.properties file

Changelog

All Liquibase changes are logged through a changelog file : changelog-master.yaml , which will list sequentially all the changes made to the database.

Here is an example

databaseChangeLog:
- include:
file: src/main/resources/db/changelog/0001/changelog.yaml
- include:
file: src/main/resources/db/changelog/0002/0002-01_create_new_table.sql

Changeset

The changeset is a unit of change which is identified by an id and an author.

A changeset can be written in XML, JSON, SQL, YML , here is a how a changeset written in SQL will look:

--liquibase formatted sql
--changeset author:id
CREATE TABLE ...-- rollback DROP TABLE ...;

So let’s say you want to create a new table product that have a new a sequence as a primary key. Here is how this change will look with a SQL format changeset :

--liquibase formatted sql
--changeset eliedaher:1
CREATE SEQUENCE product_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE TABLE product (
id INTEGER NOT NULL DEFAULT NEXTVAL('product_id_seq') PRIMARY KEY,
key CHARACTER VARYING(64),
description CHARACTER VARYING(255)
);
-- rollback DROP TABLE product;
-- rollback DROP SEQUENCE product_id_seq;

Use cases

Here is the most used commands in Liquibase

Update on database

Updating allows us to deploy all the changeset that are not yet executed

mvn liquibase:update

Tag current database state

Tagging allows us to version database states, so that we can rollback to a previous state easily in future

mvn liquibase:tag -Dliquibase.tag=10

Rollback by changeset count

mvn liquibase:rollback -Dliquibase.rollbackCount=2

Rollback to a specific date

mvn liquibase:rollback -Dliquibase.rollbackDate=2021-04-30T11:30:00

Rollback to a previous tag

mvn liquibase:rollback -Dliquibase.rollbackTag=9

Check all other commands here

Some tips

Use SQL instead of other format

Changes can be written in XML, JSON, SQL, YML. In all the projects that I worked on, we chose SQL since it is well known by most of the contributors of our projects and no learning curve was needed to master it.

Organising changesets by feature

The way I usually organise the changesets is by creating a folder for each new feature, with the folder being identified by a feature id, that way each feature will have it’s own changelog file.

Changelog per feature

By doing that, the changelog-master will contain a list of features changelogs.

Disabling automatic migration

Whenever you compile the spring boot application, Liquibase will run its migration. So instead of enabling that feature, I opt out to disable it, and run the migration as a dedicated task by itself.

The way to disable database migration on each compilation is by setting the following property to false:

spring.liquibase.enabled=false

Liquibase has improved the way we worked and allowed us to evolve and perform migration on our database seemingly. Other alternatives on the market are available, such as Flyway, which does the job.

An example of integrating Liquibase in a spring boot application is present here.

Feel free to comment, if you have any question or if I missed something 😬.

--

--