Liquibase with Spring Boot
About
Liquibase is a powerful tool that provides a declarative way to manage database schema changes. With Liquibase, schema changes can be defined in a change log file, which can be versioned and tracked just like the application code. This makes it easy to manage database schema changes across different environments, such as development, staging, and production.
Spring Boot has built-in support for Liquibase, which means Liquibase can easily integrate into the Spring Boot application by adding the liquibase-core dependency to the project's Maven or Gradle build file, and configuring it with the necessary properties, such as the JDBC URL, username, and password.
To use Liquibase in a Spring Boot application, create a Liquibase change log file, which defines the changes to be applied to the database schema. It can be in YAML or XML or any other format which is supported, and can include a series of change sets that define the individual changes to be made to the schema.
Overall, using Liquibase as part of a Spring Boot project can help us manage database schema changes more effectively and maintain the consistency of our database schema across different environments.
Init Container vs Main Container wrt liquibase
Init Container
An init container is a separate container that runs and completes before the main application container starts. It is primarily used for performing initialization tasks or pre-requisites required by the main container. In the context of Liquibase, an init container can be used to apply database schema changes or migrations before the main application container starts. This ensures that the database is properly prepared before the application attempts to connect to it. Liquibase can be executed as part of the init container, allowing us to manage database changes as a separate initialization step. In case of any issues with init container, main container won't be starting.
Main Container
The main container refers to the primary application container that runs the actual application logic. In the case of a Spring Boot application, the main container would be responsible for running the Spring Boot application itself including the liquibase changes.
The separation of Liquibase execution into an init container allows for better control over the database initialization process and ensures that the database schema changes are applied before the application starts. This approach helps to maintain consistency and reduces the risk of the application encountering issues due to incompatible database schema versions.
Example
Firstly, we will need mysql instance up and running. We will use docker-compose method to bring mysql.
docker-compose.yaml
version: "3.9"
# https://docs.docker.com/compose/compose-file/
services:
db-mysql:
container_name: db-mysql
image: mysql:8.0.29
ports:- "3306:3306"
environment:MYSQL_ROOT_PASSWORD: root
volumes:- mysql-data:/var/lib/mysql
volumes:
mysql-data:
driver: local
networks:default:
name: company_default
docker-compose up db-mysql

We will create liquibase-example-service spring boot project.
Add the following dependencies to the pom.xml file
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
</dependencies>
Create the main application.java class
package com.company.project;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Add the required properties in application.yaml file
server:
port: 4040
spring:
datasource:
url: jdbc:mysql://localhost:3306/liquibase-example-schema/liquibase-example-schema?createDatabaseIfNotExist=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
liquibase:
enabled: true
change-log: db/changeLog-master.yaml
logging:
level:
liquibase: DEBUG
Now, let's create changelog files. We will create master changelog file and it will have reference to separate changelog files.

changeLog-master.yaml
databaseChangeLog:
- includeAll:
path: tables-setup-0_1
relativeToChangelogFile: true
add-table-books-04052023.yaml
databaseChangeLog:
- changeSet:
id: 2
author: [email protected]
labels: books
context: books
comment: This is the table to hold books data
changes:
- createTable:
tableName: books
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
# Add a version attribute here
version: 1.0.0
add-table-users-03052023.yaml
databaseChangeLog:
- changeSet:
id: 1
author: [email protected]
labels: users
context: users
comment: This is the table to hold users data
changes:
- createTable:
tableName: users
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false
- column:
name: age
type: int
constraints:
nullable: false
- column:
name: contact
type: int
constraints:
nullable: false
- column:
name: address
type: varchar(100)
constraints:
nullable: false
# Add a version attribute here
version: 1.0.0
update-table-users-05052023.yaml
databaseChangeLog:
- changeSet:
id: 3
author: [email protected]
labels: books
context: books
comment: Adding author column to the books table
changes:
- addColumn:
tableName: books
columns:
- column:
name: author
type: varchar(50)
Overall, the folder structure will look like below

Build the project with below maven command and run the application
mvn clean install

mvn spring-boot:run


From the above logs, we can see that liquibase has applied the database changes and let's verify from the MySQl Workbench as well.

Files are attached for the reference below.
Last updated