Database version management Liquibase integration of SpringBoot series


The previous articles introduced several ways to initialize the database after the project is started. Next, let’s take a look at how to use Liquibase to implement database version management.

SpringBoot has built-in support for Liquibase, which is very easy to use in projects

I. Project construction

1. Dependency

First build a standard SpringBoot project, the relevant versions and dependencies are as follows

This project is developed with SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
        <version>3.8.0</version>
    </dependency>
</dependencies>

This article uses the MySql database, version 8.0.31; the core of Liquibase depends on liquibase-core, the version recommended to use SpringBoot matching version, generally speaking, no special specification is required

2. Configuration

Configuration file resources/application.yml

# default database name
database:
  name: tt

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/${<!-- -->database.name}?useUnicode=true & amp;characterEncoding=UTF-8 & amp;useSSL=false & amp;serverTimezone= Asia/Shanghai
    username: root
    password:
  liquibase:
    change-log: classpath:liquibase/master.xml
    enabled: true

record:
  level:
    root: info
    org:
      springframework:
        jdbc:
          core: debug

The key configurations are spring.liquibase.change-log and spring.liquibase.enabled

The first specified is the xml file corresponding to the change-log, and its content is as follows

liquibase core xml file resources/liquibase/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"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
    http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">

    <include file="liquibase/changelog/000_initial_schema.xml" relativeToChangelogFile="false"/>

</databaseChangeLog>

The above xml depends on an xml file, such as the first main definition is the initialized table structure

The corresponding content of resources/changelog/000_initial_schema.xml is as follows

<?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"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">

    <property name="now" value="now()" dbms="mysql"/>
    <property name="autoIncrement" value="true"/>

    <changeSet id="00000000000001" author="YiHui">
        <sqlFile dbms="mysql" endDelimiter=";" encoding="UTF-8" path="liquibase/data/init_schema_221209.sql"/>
    </changeSet>

    <changeSet id="00000000000002" author="YiHui">
        <sqlFile dbms="mysql" endDelimiter=";" encoding="UTF-8" path="liquibase/data/init_data_221209.sql"/>
    </changeSet>
</databaseChangeLog>

In the above configuration file, the core point is where the id is required to be globally unique, and sqlFile represents the SQL statement corresponding to this change; a corresponds to a change. Note that after each change is completed, it cannot be modified (the content of the sql file cannot be changed), and the changeSet itself should not be modified.

Next, look at the corresponding sql file

resources/liquibase/data/init_schema_221209.sql The corresponding schema-related table structure is defined as follows

CREATE TABLE `user`
(
    `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key ID',
    `third_account_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Third-party user ID',
    `user_name` varchar(64) NOT NULL DEFAULT '' COMMENT 'username',
    `password` varchar(128) NOT NULL DEFAULT '' COMMENT 'password',
    `login_type` tinyint NOT NULL DEFAULT '0' COMMENT 'Login method: 0-WeChat login, 1-account password login',
    `deleted` tinyint NOT NULL DEFAULT '0' COMMENT 'Delete',
    `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Create time',
    `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'last update time',
    PRIMARY KEY (`id`),
    KEY `key_third_account_id` (`third_account_id`),
    KEY `user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='User login form';

The initialization data corresponding to resources/liquibase/data/init_data_221209.sql is defined as follows

INSERT INTO `user` (id, third_account_id, `user_name`, `password`, login_type, deleted)
VALUES (1, 'a7cb7228-0f85-4dd5-845c-7c5df3746e92', 'admin', 'admin', 0, 0);

II. Project presentation

1. Test

After the above configuration is completed, no special processing is required in the main project structure project. Let’s write a simple startup test

@Slf4j
@SpringBootApplication
public class Application implements ApplicationRunner {<!-- -->

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {<!-- -->
        SpringApplication.run(Application.class);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {<!-- -->
        List list = jdbcTemplate.queryForList("select * from user limit 2");
        log.info("The project started successfully, initialized data: {}", list);
    }
}

Look at the output after direct execution (before execution, please make sure that the database has been successfully created; if not, an exception will be thrown)

2. Incremental changes

The above demonstration is the initialization process; in the actual development process, if there is an incremental change, for example, a new test data needs to be added now, our operation process can be as follows

Add a new 001_change_schema.xml file under the liquibase/ directory, and the ChangeSet related to subsequent incremental changes are placed in this xml file; In the master.xml file, add the introduction of the above xml file

 <include file="liquibase/changelog/001_change_schema.xml" relativeToChangelogFile="false"/>

The second is the content of the resources/liquibase/changelog/001_change_schema.xml file

<?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"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">

    <property name="now" value="now()" dbms="mysql"/>
    <property name="autoIncrement" value="true"/>

    <!-- When a new change occurs later, a corresponding changeSet is added for each change -->
    <changeSet id="00000000000003" author="YiHui">
        <sqlFile dbms="mysql" endDelimiter=";" encoding="UTF-8" path="liquibase/data/init_data_221212.sql"/>
    </changeSet>
</databaseChangeLog>

The above changeSet contains initialization related sql files, the contents are as follows

INSERT INTO `user` (id, third_account_id, `user_name`, `password`, login_type, deleted)
VALUES (2, 'a7cb7228-0f85-4dd5-845c-11123123', 'new', 'new', 0, 0);

Start again to verify whether new data has been added

3. Summary

This article mainly introduces how SpringBoot combines Liquibase to realize database version management. The core knowledge points are not introduced much. When actually using it, pay attention

For each change, add a new , and ensure that all ids are unique; after the change is completed, do not modify the content of the corresponding sql file

Liquibase itself also has some related knowledge points, such as version rollback, tag semantics, etc. The next blog post will specifically introduce the core knowledge points of Liquibase itself

If you are interested in the initial data after the project starts, please check it out

  • [DB series] Database initialization – datasource configuration method | A gray blog
  • [DB series] Database initialization – jpa configuration method | A gray blog
  • [DB Series] Database Initialization – DataSourceInitializer Method | A Gray Blog

III. Source code and related knowledge points that cannot be missed

0. Project

  • Project: https://github.com/liuyueyi/spring-boot-demo
  • Source code: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/162-liquibase

1. WeChat Official Account: One Gray Blog

It is not as good as a letter of faith. The above content is purely a family opinion. Due to limited personal ability, it is inevitable that there will be omissions and mistakes. If you find a bug or have a better suggestion, you are welcome to criticize and correct. Thank you

The following is a gray personal blog, which records all the blog posts in study and work. Welcome to visit

  • Yihuihui Blog personal blog https://blog.hhui.top
  • A gray blog-Spring special blog http://spring.hhui.top