Spring Tips: Liquibase

Overview

Spring Tips: Liquibase

Getting Started with Postgres

Before we can do anything, we’ll need a valid PostgreSQL database to which we can connect. You can run a Postgres instance in a Docker image. We’ll need more than one database to develop, to simulate development (your local machine, dev) and production (prod) environments, for example. I have this handy little script that quickly spins up dummy PostgreSQL instances. Put this in a file called postgres.sh, and don’t forget to run chmod a+x postgres.sh to make it executable. Add it to your PATH so that it’s discoverable.

postgres.sh
#!/usr/bin/env bash

NAME=${1}-postgres
PORT=${2:-5432}

docker run --name  $NAME  \
	-p ${PORT}:5432 \
	-e POSTGRES_USER=user \
	-e PGUSER=user \
	-e POSTGRES_PASSWORD=pw \
	postgres:latest

You can use it to create a development (dev) database, thusly:

./postgres.sh dev 5500

This will spin up an instance of the PostgreSQL Docker image called dev-postgres and run it on port 5500. If you don’t specify a port, it’ll use the default of 5432. The username is user and the password is pw. You can connect to the instance using the psql CLI, thusly:

PGPASSWORD=pw psql -U user -h localhost -p 5500 user

We’ll need another PostgreSQL instance for our production (prod) build, too.

PGPASSWORD=pw psql -U user -h localhost -p 5400 user

Getting Started

You’ve probably probably got a database with some schema on which you’d like to build. So, you’ll want to use that as a starting spot. Configure the Apache Maven build to use the liquibase-maven-plugin:


    org.liquibase
    liquibase-maven-plugin
    4.5.0
    
        
            src/main/resources/liquibase.properties
        
    

Once you’ve got that, specify a file called src/main/resources/liquibase.properties. In it, put:

url=jdbc:postgresql://localhost:5500/user
username=user
password=pw
driver=org.postgresql.Driver
changeLogFile=src/main/resources/db/changelog/db.changelog-master.xml
outputChangeLogFile=src/main/resources/db/changelog/generated.xml

The following Liquibase Maven plugin (not Spring Boot) incantation connects to the schema of your choice and uses it to create a changelog whose contents it will write to whatever path we specify for outputChangeLogFile (src/main/resources/db/changelog/generated.xml).

mvn liquibase:generateChangeLog

The result will be in src/main/resources/db/changelog/generated.xml. Inspect it and you’ll see it’s created discrete actions and represented them (very verbosely) using XML. Rename generated.xml to src/main/resources/db/changelog/changelog-v1.0.xml. Spring Boot will automatically pick up the changelogs from src/main/resources/db/changelog/db.changelog-master.xml, so let’s add an include directive to include changelog-v1.0.xml.

">
xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
   <include file="db/changelog/changelog-v1.0.xml"/>
databaseChangeLog>

Alternatively, you could add everything from inside the outer most tag of changelog-v1.0.xml and add it to the body of changelog.xml, foregoing the includes. This can be nice if you want to see everything in one place. It’s also, I think, easier to follow the story if you’re doing SQL formatted changelogs, which we’ll explore momentarily.

When Spring Boot starts, it will read this changelog and apply it to the Spring Boot DataSource. Youll need to specify the values used to connect to that DataSource in the Spring Boot environment. The easiest way to specify these values in a development environment is application.properties:

spring.datasource.username=user
spring.datasource.password=pw
spring.datasource.url=jdbc:postgresql://localhost:5500/user
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.xml

The Spring Boot application connects to the development database by default.

Making a Change

Let’s suppose we want to evolve the database schema, perhaps by adding a new column. There are two different ways to handle this: we could drive with the Liquibase changelogs, or we could derive the Liquibase chagelogs. If we drive with Liquibase, then we evolve the database through additions to the Liquibase changelog. If we derive with Liquibase, then we evolve the database through additions to the SQL schema itself and we capture those changes as Liquibase changelogs. Either way, the result is that we should have a durable way to recover, enforce, and rollback that change to the schema. Let’s first drive the changes with the Liquibase migration.

Create a new file, src/main/resources/db/changelog/changelog-v1.1.xml with the following contents:

">
xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">

    <changeSet author="jlong" id="2022022105452668229700">
        <addColumn tableName="articles">
            <column name="published" type="timestamp"/>
        addColumn>
    changeSet>

databaseChangeLog>

We’re using one of the Liquibase commands, addColumn, to add a column to a table.

If writing these tedious XML files doesn’t speak to ya (and who can blame ya?), then you’ll be pleased to know that there’s a way to derive the the changelog by inspecting the structure of a schema. We’ll use the Maven plugin to do this. First, you need to delete changelog-v1.1.xml if you created it before. Then, we’ll need to add some properties to our liquibase.properties to specify the baseline database (in this case our production database) and the local, development database.

url=jdbc:postgresql://localhost:5400/user
username=user
password=pw
driver=org.postgresql.Driver
changeLogFile=src/main/resources/db/changelog/db.changelog-master.xml

outputChangeLogFile=src/main/resources/db/changelog/generated.xml
diffChangeLogFile=src/main/resources/generated-diff.xml

referenceUrl=jdbc:postgresql://localhost:5500/user
referenceDriver=org.postgresql.Driver
referenceUsername=user
referencePassword=pw

Here, we’ve specified the original database (which is the baseline) and the updated database. Let’s use the Maven plugin to capture the delta between those schema:

mvn liquibase:diff

Liquibase writes out a change log in whatever path you’ve specified for diffChangeLogFile. Inspect the file and you’ll see its virtually the same as (but not indentical to) the changeset we wrote out by hand earlier. Rename the file to src/main/resources/db/changelog/changelog-v1.2.xml. Update changelog.xml to not include changelog-v1.1.xml but to include both changelog-v1.0.xml and changelog-v1.1.xml.

Now, the next time you run the Spring Boot application, Liquibase will attempt to teach that database all the new changes. When you next deploy your application to production, you’ll have captured all the database migrations and they’ll be applied automatically.

Rolling Back

In the last example, we added a new column in an addColumn changeset. What happens if we want to back out of some changes to the schema. What if something’s gone wrong and it won’t work and we just need to know if our application has any hope of successfully running in production in again? We can always use Liquibase to rollback changes made to the database schema. There are a number of different ways to select which changeset rollbacks we apply, but the easiest is to simply execute N of the latest changeset rollbacks, like this:

mvn liquibase:rollback -Dliquibase.rollbackCount=1

The rollbackCount number is arbitrary. I’ve chosen to simply rollback the very latest changeset.

Now, you should see that the new column, published, no longer exists. Remember, the Maven plugin applies its actions to whatever you’ve specified in the liquibase.properties for the url key.

Initializing a Bean Only After the Application’s DataSource Has Been Initialized with Liquibase

You may have work that you want to execute after the Spring Boot application has started up and after the Liquibase database migration has finished. Annotate the bean with @DependsOnDatabaseInitialization, like this:

@Bean
@DependsOnDatabaseInitialization
ApplicationRunner runner(ArticleService service) {
    return args -> service.findAll().forEach(System.out::println);
}
You might also like...

mall-swarm是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba、Spring Boot 2.3、Oauth2、MyBatis、Docker、Elasticsearch、Kubernetes等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。文档齐全,附带全套Spring Cloud教程。

mall-swarm是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba、Spring Boot 2.3、Oauth2、MyBatis、Docker、Elasticsearch、Kubernetes等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。文档齐全,附带全套Spring Cloud教程。

mall-swarm 友情提示 快速体验项目:在线访问地址。 全套学习教程:《mall学习教程》。 Spring Cloud全套教程:《SpringCloud学习教程》。 专属学习路线:学习不走弯路,整理了套非常不错的《mall专属学习路线》。 项目交流:想要加群交流项目的朋友,可以加入mall项目

Jan 3, 2023

芋道 mall 商城,基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

芋道 mall 商城,基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

[toc] 友情提示:近期在升级和优化该项目,建议先 Star 本项目。主要在做几个事情: 1、微服务技术选型以 Spring Cloud Alibaba 为中心。 2、修改项目分层,并合并部分服务,简化整体服务的复杂性。 3、将管理后台从 React 重构到 Vue 框架。 交流群:传送门 前言

Jan 6, 2023

about learning Spring Boot via examples. Spring Boot 教程、技术栈示例代码,快速简单上手教程。

about learning Spring Boot via examples. Spring Boot 教程、技术栈示例代码,快速简单上手教程。

Spring Boot 学习示例 Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用。 Spring Boot 中文索引 | Spring Cloud学习示例代码 | Spring

Jan 1, 2023

spring boot 实践学习案例,是 spring boot 初学者及核心技术巩固的最佳实践。另外写博客,用 OpenWrite。

spring boot 实践学习案例,是 spring boot 初学者及核心技术巩固的最佳实践。另外写博客,用 OpenWrite。

推荐工具: 微信公众号 Markdown 编辑器 - OpenWrite:Markdown 微信编辑器是一款专业强大的微信公众平台在线编辑排版工具,提供手机预览功能,让用户在微信图文 、文章、内容排版、文本编辑、素材编辑上更加方便。 - 更多介绍 博客群发平台 一、支持泥瓦匠 Spring Boot

Jan 5, 2023

Spring Boot基础教程,Spring Boot 2.x版本连载中!!!

Spring Boot基础教程,Spring Boot 2.x版本连载中!!!

Spring Boot基础教程 本项目内容为《Spring Boot基础教程》的程序样例。 专题目标:打造全网内容最全,比收费教程更好的Spring Boot免费教程! 加入社群:如果你正在学习Spring Boot,不妨加入我们的Spring技术交流群,一起成长! 如何支持: 关注我的公众号”程序

Jan 6, 2023

Not only Spring Boot but also important knowledge of Spring(不只是SpringBoot还有Spring重要知识点)

Not only Spring Boot but also important knowledge of Spring(不只是SpringBoot还有Spring重要知识点)

在线阅读 : https://snailclimb.gitee.io/springboot-guide (上面的地址访问速度缓慢的建议使用这个路径访问) 重要知识点 基础 Spring Boot 介绍 第一个 Hello World 第一个 RestFul Web 服务 Spring 如何优雅读取配

Jan 3, 2023

Spring-Boot-Plus is a easy-to-use, high-speed, high-efficient,feature-rich, open source spring boot scaffolding

Spring-Boot-Plus is a easy-to-use, high-speed, high-efficient,feature-rich, open source spring boot scaffolding

Everyone can develop projects independently, quickly and efficiently! What is spring-boot-plus? A easy-to-use, high-speed, high-efficient, feature-ric

Dec 31, 2022

开源论坛、问答系统,现有功能提问、回复、通知、最新、最热、消除零回复功能。功能持续更新中…… 技术栈 Spring、Spring Boot、MyBatis、MySQL/H2、Bootstrap

开源论坛、问答系统,现有功能提问、回复、通知、最新、最热、消除零回复功能。功能持续更新中…… 技术栈 Spring、Spring Boot、MyBatis、MySQL/H2、Bootstrap

码问社区 在线演示地址 www.mawen.co 功能列表 开源论坛、问答系统,现有功能提问、回复、通知、最新、最热、消除零回复功能。功能持续更新中…… 技术栈 技术 链接 Spring Boot http://projects.spring.io/spring-boot/#quick-start

Dec 30, 2022
Owner
Josh Long
Josh (@starbuxman) is the Spring Developer Advocate at VMware, an open-source hacker, book/video author and speaker
Josh Long
该仓库中主要是 Spring Boot 的入门学习教程以及一些常用的 Spring Boot 实战项目教程,包括 Spring Boot 使用的各种示例代码,同时也包括一些实战项目的项目源码和效果展示,实战项目包括基本的 web 开发以及目前大家普遍使用的线上博客项目/企业大型商城系统/前后端分离实践项目等,摆脱各种 hello world 入门案例的束缚,真正的掌握 Spring Boot 开发。

Spring Boot Projects 该仓库中主要是 Spring Boot 的入门学习教程以及一些常用的 Spring Boot 实战项目教程,包括 Spring Boot 使用的各种示例代码,同时也包括一些实战项目的项目源码和效果展示,实战项目包括基本的 web 开发以及目前大家普遍使用的前

十三 4.5k Dec 30, 2022
一个涵盖六个专栏:Spring Boot 2.X、Spring Cloud、Spring Cloud Alibaba、Dubbo、分布式消息队列、分布式事务的仓库。希望胖友小手一抖,右上角来个 Star,感恩 1024

友情提示:因为提供了 50000+ 行示例代码,所以艿艿默认注释了所有 Maven Module。 胖友可以根据自己的需要,修改 pom.xml 即可。 一个涵盖六个主流技术栈的正经仓库: 《Spring Boot 专栏》 《Spring Cloud Alibaba 专栏》 《Spring Clou

芋道源码 15.7k Dec 31, 2022
参考 DDD/Clean Architecture 设计理念,整合 Spring Boot/Spring Security/Mybatis Plus/Vavr 的 Spring Realworld 应用案例

Demo · 更多项目 · 参考资料 ms-spring-ddd-examples Unified Domain-driven Layered Architecture for MicroService Apps,试图探索一套切实可行的应用架构规范,可以复制、可以理解、可以落地、可以控制复杂性的指导

王下邀月熊 19 Sep 23, 2022
Spring Kurulumundan Başlayarak, Spring IOC ve Dependency Injection, Hibernate, Maven ve Spring Boot Konularına Giriş Yapıyoruz.

Spring Tutorial for Beginners File Directory Apache Tomcat Apache Tomcat - Eclipse Bağlantısı Spring Paketlerinin İndirilmesi ve Projeye Entegrasyonu

İbrahim Can Erdoğan 11 Apr 11, 2022
Spring Boot JdbcTemplate example with SQL Server: CRUD Rest API using Spring Data JDBC, Spring Web MVC

Spring Boot JdbcTemplate example with SQL Server: Build CRUD Rest API Build a Spring Boot CRUD Rest API example that uses Spring Data Jdbc to make CRU

null 7 Dec 20, 2022
Spring Boot & MongoDB Login and Registration example with JWT, Spring Security, Spring Data MongoDB

Spring Boot Login and Registration example with MongoDB Build a Spring Boot Auth with HttpOnly Cookie, JWT, Spring Security and Spring Data MongoDB. Y

null 15 Dec 30, 2022
Spring Boot Login and Registration example with MySQL, JWT, Rest Api - Spring Boot Spring Security Login example

Spring Boot Login example with Spring Security, MySQL and JWT Appropriate Flow for User Login and Registration with JWT Spring Boot Rest Api Architect

null 58 Jan 5, 2023
Demo microservice architecture with Spring ,Spring Cloud Gateway , Spring Cloud config server , Eureuka , keycloak and Docker.

spring-microservice Demo microservice architecture with Spring ,Spring Cloud Gateway , Spring Cloud config server , Eureuka , keycloak and Docker. Arc

null 4 Sep 13, 2022
Spring Boot JWT Authentication example with Spring Security & Spring Data JPA

Spring Boot JWT Authentication example with Spring Security & Spring Data JPA

null 1 Jan 26, 2022
Spring REST service built with Spring initializr and Spring Data.

Spring REST Service Generated with start.spring.io, using Spring Data. Documented using Spring REST Docs. Spring Initializr - Generate new Spring Rest

null 1 Jan 28, 2022