Skip to content

rubelhassan/spring-liquibase-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring Liquibase Integration Demo

Overview

This project demonstrates examples of Liquibase integration with Spring Boot and Maven and how to manage database schema evolution over time.

Running the Project Locally

Requirements

Please make sure the above requirements are available on your local machine, please see the references section.

Before running the project please make sure to build the project JAR file using following command

./mvnw clean package

Run with Docker

docker-compose up

Run with JAVA

If docker is not installed on your machine then you can deploy JAR file directly, in that case try to change configuration at application.properties file.

java -jar -Dspring.config.location=src/main/resources/application.properties target/spring-liquibase-demo-0.0.1-SNAPSHOT.jar

The project should be up and running on port 8080 on your localhost. This is a simple RESTful web service provides endpoints to create users and manage their tasks. You can access project's Swagger UI for more details on REST endpoints.

Introduction to Liquibase

Liquibase Community is an open source project that helps rapidly track, version, and deploy database schema changes. The following sections will cover basic concepts of Liquibase and how you can integrate Liquibase with Spring boot and Maven.

Liquibase CLI Installation

Liquibase doesn't require any installation using with Spring boot and Maven. But on servers Ant or Maven is not always available. So in this case it's better to use Liquibase CLI and gives more control. Installing Liquibase CLI on Linux/Unix/Mac | Liquibase Docs

Changeset

Liquibase uses changeset to identify each change to the database. Each changeset has an “id” and “author” attribute which, along with the directory and file name of the changelog file, uniquely identify a change. A changeset can be written in SQL, XML, YAML, and JSON formats.

An example of changeset in SQL format.

--changeset Bob:157
 CREATE TABLE person (
 id int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
 firstname varchar (50) NULL,
 lastname varchar (50) NOT NULL,
 state bpchar (2) NULL,
 username varchar (8) NULL,
 CONSTRAINT person_pkey PRIMARY KEY (id)
);
--rollback drop table if exists person

Writing changesets using YAML, XML or JSON format allows it to work across databases, e.g. MSSQL and PostgreSQL, unlike SQL changesets which may be database specific.

Below is an example of changeset in YAML format.

databaseChangeLog:
  - changeSet:
      id: 1
      author: bob
      changes:
        - createTable:
            tableName: person
            columns:
              - column:
                  name: id
                  type: int
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: firstname
                  type: varchar(50)
              - column:
                  name: lastname
                  type: varchar(50)
                  constraints:
                    nullable: false

Changelogs

Liquibase uses a changelog to explicitly list database changes in order. The changelog acts as a ledger of changes and contains a list of changesets (units of change) that Liquibase can execute on a database. Liquibase supports changelogs file also in SQL, XML, YAML, and JSON formats.

Liquibase supports “plain SQL” changelog files. Formatted SQL files use comments to provide Liquibase with metadata. Each SQL changelog file must begin with the following comment:

--liquibase formatted sql

Each changeset in a formatted SQL changelog file begins with a comment of the form:

--changeset author:id attribute1:value1 attribute2:value2 [...]

An example changelog SQL file which contains a set of changes that need to be applied to DB

--liquibase formatted sql
--changeset <author name>:<a unique identifier for the SQL changeset>
<SQL statements go here>
--rollback <rollback SQL statements>
--changeset <author name>:<another unique identifier>
<SQL statements go here>
--rollback <rollback SQL statements>

changeset and changelog in SQL format seem most convenient for writing and debugging if database agnostic in not a goal

See more

Naming SQL changelog files

0000_initial_database_setup.sql
0010_add_some_tables.sql
0020_create_some_procedures.sql
0030_you_can_also_have_xml_changelogs.xml

By using an initial four-digit number, the files will get sorted in a predictable order. As developers add more changesets, leave some ‘space’ in the numbering sequence in case we ever need to add a new changeset in between two existing changesets. Notice that we can also include changelogs in other formats.

Each changeset inside a changelog file can be prefixed by the 4-digit number joining an underscore with the sequence number of the changeset in that file.

--changeset Bob:0000_1
<SQL changes ….>
--changeset Bob:0000_2
<SQL changes ….>

These are not any rules imposed by Liquibase but can help to achieve a nice organization in versioning.

Creating a Master changelog File

We can maintain a master changelog file to point all the changelog files for migrations. Below is an example of a master changelog file where we include all changelogs in sorted order by name. We can also include changelogs in a custom order by using include tag.

databaseChangeLog:
  - includeAll:
      path: changes
      relativeToChangelogFile: true

Liquibase CLI and Maven

liquibase.properties file

A liquibase.properties file is a text-based file that allows one to store properties that don't change often. We can typically use this file to specify our database connection information and sensitive data that Liquibase will use. We can even maintain separate properties file like liquibase-.properties file for different environments.

An example of liquibase properties file

changeLogFile=src/main/resources/db/changelog/db.changelog-master.yaml
url=jdbc:postgresql://<host>:5432/<db_name>
username=<username>
password=<password>
driver=org.postgresql.Driver
contexts=dev

See more on Creating and Configuring Liquibase.Properties Files | Liquibase Docs

Integrate Liquibase with Maven

You can easily integrate Liquibase with Maven using plugin to run migrations smoothly with maven commands.

<plugin>
	<groupId>org.liquibase</groupId>
	<artifactId>liquibase-maven-plugin</artifactId>
	<version>4.0.0</version>
	<configuration>
		<propertyFileWillOverride>true</propertyFileWillOverride>
		<propertyFile>/path/to/propertiesfile</propertyFile>
	</configuration>
</plugin>

While it's convenient to use Liquibase auto migration with Spring boot, but there is no easy way for rollbacks. That's why Maven integration is a good choice for other options. We can keep both in a project.

See more on Setting up a Liquibase project with Maven and PostgreSQL

Commands to Update and Rollback in Liquibase with Maven

Update changes to the database that need to be applied

mvn liquibase:update -Dliquibase.contexts=dev -DliquibasePropertiesFile=src/main/resources/db/liquibase-dev.properties

Rollback can be performed on different parameters. The easiest one is to revert the last n changes.

mvn liquibase:rollback -Dliquibase.rollbackCount=<n> -DliquibasePropertiesFile=src/main/resources/db/liquibase-dev.properties 

See more on Commands | Liquibase Docs

Liquibase and Spring Boot

Spring Boot provides integration with Liquibase that gets autoconfigured when the Liquibase dependency is added to the POM, and runs migrations automatically on application startup. All you need is to put your change log in “db/changelog/db.changelog-master.yaml” for master changelog and add the "liquibase-core" dependency into the pom.xml.

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
    <version>4.0.0</version>
</dependency>

Default behaviors can be changed and configured through application.properties. For example to disable liquibase migration you can make spring.liquibase.enabled property value to false.

spring.liquibase.enabled=false

Conclusion

This is not a complete guide on Liquibase, please refer to the official liquibase doc if you’re interested to learn more about a specific scenario. Liquibase is based on Martin Fowler’s Evolutionary Database - an article that covers the concepts and practices of Evolutionary Database Architecture.

References

About

A demo project on Spring Boot and Liquibase integration

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published