liquibase 数据库重构工具

1. Liquibase简介

Liquibase是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化(包括数据库结构和数据)都保存在changelog文件中,便于版本控制,它的目标是提供一种数据库类型无关的数据库类型无关的解决方案,通过执行schema类型的文件来达到迁移。

-> 官方文档

Liquibase特性

  • 支持几乎所有主流的数据库,如Mysql、PostgreSql、Oracle、SQL server、DB2等。

  • 支持多发开者的协作维护

  • 日志文件支持多种格式,如xml、yaml、JSON、SQL等

  • 支持上下文相关逻辑

  • 生成数据库变更文档

  • 支持多种运行方式,如命令行、spring集成、maven插件、Gradle插件等

代码工程

简单案例

实验mysql数据初始化

  1. 引入pom
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>liquibase</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>liquibase</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>17</maven.compiler.release>
    </properties>
    <parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.4.5</version>
    </parent>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

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

    <build>
    <plugins>
    <plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>4.29.1</version>
    <configuration>
    <!--生成Changelog的输出目录-->
    <outputChangeLogFile>${basedir}/src/main/resources/liquibase/generate/changeLog.xml
    </outputChangeLogFile>
    <!--DB连接信息-->
    <driver>com.mysql.jdbc.Driver</driver>
    <url>jdbc:mysql://localhost:3306/demo?useSSL=false</url>
    <username>root</username>
    <password>xiaoyuge</password>
    <dropFirst>false</dropFirst>
    <verbose>true</verbose>
    <logging>debug</logging>
    <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
    <outputFileEncoding>UTF-8</outputFileEncoding>
    <propertyFileWillOverride>true</propertyFileWillOverride>
    </configuration>
    </plugin>
    </plugins>
    </build>
    </project>
  2. 创建数据库表
    1
    2
    3
    4
    5
    CREATE TABLE `user_info` (
    `id` int NOT NULL AUTO_INCREMENT,
    `name` varchar(50) default null,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  1. changelog配置目录

    运行后会在resource/liquibase/generate下面生成changeLog.xml文件
  1. 创建master.xml,包含需要的changelog目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?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/generate/changeLog.xml" />

    </databaseChangeLog>
  2. yml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    spring:
    datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?createDatabaseIfNotExist=true&allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: xiaoyuge
    driver-class-name: com.mysql.cj.jdbc.Driver

    liquibase:
    change-log: change-log: classpath:liquibase/master.xml
    contexts: dev
    enabled: true
    #用于跟踪并发Liquibase使用情况的表的名称
    database-change-log-lock-table: DATABASECHANGELOGLOCK
    #用于跟踪更改历史记录的表的名称
    database-change-log-table: DATABASECHANGELOG
  3. 启动程序,等待1分钟后,数据库会创建两张记录表

    Liquibase默认会生成databasechangelog和databasechangeloglock表(记录变更日志)

多数据源模式

每个数据源配置都独立配置一套资源文件

  1. yml配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    spring:
    datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?createDatabaseIfNotExist=true&allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: xiaoyuge
    driver-class-name: com.mysql.cj.jdbc.Driver
    liquibase:
    change-log: classpath:liquibase/datasource1/master.xml
    datasource2:
    username: root
    password: 123456
    jdbc-url: jdbc:mysql://localhost:3306/web
    driver-class-name: com.mysql.jdbc.Driver
    liquibase:
    change-log: classpath:liquibase/datasource2/master.xml
  2. 注册Bean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    @Configuration
    public class LiquibaseConfiguration {


    /**
    * datasource1
    */
    @Bean
    public SpringLiquibase datasource1Liquibase() {
    // 获取对应数据源
    DataSource dataSource;
    SpringLiquibase liquibase = new SpringLiquibase();
    // Liquibase文件路径
    liquibase.setChangeLog("classpath:liquibase/datasource1/master.xml");
    liquibase.setDataSource(dataSource);
    liquibase.setShouldRun(true);
    liquibase.setResourceLoader(new DefaultResourceLoader());
    // 覆盖Liquibase changelog表名
    liquibase.setDatabaseChangeLogTable("datasource1_changelog_table");
    liquibase.setDatabaseChangeLogLockTable("datasource1_changelog_lock_table");
    return liquibase;
    }

    /**
    * datasource2
    */
    @Bean
    public SpringLiquibase datasource2Liquibase() {
    // 获取对应数据源
    DataSource dataSource;
    SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setChangeLog("classpath:classpath:liquibase/datasource2/master.xml");
    liquibase.setDataSource(dataSource);
    liquibase.setShouldRun(true);
    liquibase.setResourceLoader(new DefaultResourceLoader());
    liquibase.setDatabaseChangeLogTable("datasource2_changelog_table");
    liquibase.setDatabaseChangeLogLockTable("datasource2_changelog_lock_table");
    return liquibase;
    }
    }