Spring Boot 集成和使用 Liquibase

目录

  • 前言
  • 数据库迭代
  • Liquibase 介绍
  • Liquibase 集成
    • 工具的强大
    • Spring Boot 集成基础
    • JPA Buddy
      • 初始化 changelog
      • 差值 changelog
  • 总结

前言

部署到生产环境中的所有应用程序都应使用自动化方法迁移数据库。为了从繁琐的DDL书写中解放出来,减少人工操作引入的BUG,我们需要借助工具完成数据库迁移工作。FlyWay或Liquibase就是两个用起来比较舒服的工具。

本文将介绍 Liquibase 在 Spring Boot 中的引入和使用。阅读本文需要的准备知识:

  1. 使用 Spring Boot 创建 Web 应用,可参考:直接上手SpringBoot创建Web项目
  2. Spring JPA 的基本使用

本文开发环境:
Spring Boot: 2.7.3
语言:Kotlin
JDK:jbr-11
数据库: MySQL8.0.27
构建:Gradle 7.5

数据库迭代

使用 Spring Boot 创建带有数据库的应用很容易,JPA会自动根据 Entity 生成对应数据表,并提供 JpaRepository 接口让我们可以快速实现增删改查操作。甚至当我们更改 Entity 之后,JPA还会贴心地修改数据表以适应变化。

但是,当支持的应用版本变多,团队规模变大,迭代的次数增加之后,以上JPA自动完成的工作就有些不够用了。每次从测试数据库中提取变更,然后应用到生产数据库的过程,将会很痛苦。

那我们需要做的是使用工具记录下每次数据库结构的变化,然后合理应用这些记录,将数据库更新到合适的版本。

Liquibase 介绍

Liquibase 是一个数据库迭代管理解决方案,使您能够更快、更安全地修改和发布从开发到生产的数据库迭代。主要有三个功能模块:

  1. ChangeLog:Liquibase 使用 ChangeLog 文件按顺序保存数据库迭代的变更操作。支持的文件格式有:SQL、XML、JSON和YAML。ChangeLog 文件内容主要是 changesets 序列,详细格式可以参考下文示例。
  2. 配置文件:Liquibase 包含一个属性文件,用于存储数据库连接信息和很少更改的参数。Liquibase 根据这些信息建立与数据库之间的连接。
  3. 管理命令:Liquibase 提供了多种方式来管理数据库迭代,包括命令行、Liquibase Java API、集成到 Spring Boot使用等。

Spring Boot 默认集成对 FlyWay 与 Liquibase 的支持。也就是说以上功能在 Spring Boot 中都有默认配置,基本上不用添加额外代码。

Liquibase 集成

工具的强大

有了 Liquibase 的 ChangLog 文件,结合 Spring Boot 集成工具,我们可以用来完成什么工作呢?

  1. 自己编辑修改 ChangLog 文件,让 Spring Boot 读取该文件,修改数据库结构。
  2. 根据已经存在的数据库,生成 ChangeLog 文件,保存数据库初始化结构。
  3. 根据两个数据库的结构,生成差值 ChangeLog 文件,可用于数据库更新。

借助 Idea JpaBuddy 插件还可以完成一些更骚的操作:

  1. 根据 Entity 类,生成 ChangeLog 文件,保存数据库初始化结构。
  2. 根据 Entity 类与数据库内容,生成差值 ChangeLog 文件。

总之,结合 IDEA,Liquibase,Spring Boot,对于数据库的版本管理,基本不需要自己书写任何 SQL 语句。而且很灵活,可以完成很多自定义的工作。以上内容仅是本文举例的功能,更多功能还需要后续探索。

Spring Boot 集成基础

创建 Spring Boot Web 项目后,我们需要引入 JPA 和 Liquibase 两大组件:

    implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.7.3")
    implementation("mysql:mysql-connector-java:8.0.30")
    implementation("org.liquibase:liquibase-core:4.16.0")

然后修改 application.properties:

# datasource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=test
#jpa
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
#liquibase
spring.liquibase.enabled=true
spring.liquibase.change-log=classpath:db/changelog.sql

其中 #datasource 部分定义数据库连接信息,这是 Jpa 的基础配置。#jpa 部分 ddl-auto 设置为 none,表示 Jpa 不自动建表。#liquibase 主要定义了 changelog 文件的位置。

有了以上配置之后,Liquibase 会自动根据 DataSource 的连接信息,将 changelog 中的内容写入数据库。

如果 ddl-auto 设置为 update,JPA会自动根据 Entity 建表,根本不需要配置 Liquibase,从 changelog 中读取数据库结构。但是,关闭JPA自动建表,引入 Liquibase,相当于添加了手动管理的入口,可以帮助我们完成一些自定义的操作。

JPA Buddy

Spring Boot 可以读取 changelog 文件,生成数据库。但是 changelog 文件怎么自动生成呢?手写SQL是不可能手写的。

初始化 changelog

JPA Buddy 可以帮助我们完成这一工作。在 IDEA 中安装 JPA Buddy 插件(此处省略)之后,可以在 IDEA 右下角看到 JPA Structure 窗口。
Spring Boot 集成和使用 Liquibase_第1张图片可以看到有持久化单元信息、Liquibase和数据库连接信息。包括我们自定义的 Entity 类:Person 。数据库连接信息根据实际使用配置。

右键 Liquibase -> New -> Init Schema Changelog,在弹出的窗口选择 Model,即选择根据 Model 信息(Entity类)生成 changelog。接下来是配置 changelog 的窗口,默认会生成日期信息,这样很好,保持默认即可。文件夹标明年月,文件名前缀表示日和编号。FileType 个人会选择 SQL,因为 SQL 文件看起来简洁点。
Spring Boot 集成和使用 Liquibase_第2张图片点击确定,即可在项目 resources/db 目录下生成对应的 changelog 文件。

示例 Entity:

@Entity
class Person(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = 0L,
    @Column(nullable = false)
    var name: String = "",
    @Column(nullable = false)
    var job: String = ""
)

示例 changelog:

-- liquibase formatted sql

-- changeset hp:1663121484082-1
CREATE TABLE person
(
    id   BIGINT AUTO_INCREMENT NOT NULL,
    name VARCHAR(255)          NOT NULL,
    job  VARCHAR(255)          NOT NULL,
    CONSTRAINT pk_person PRIMARY KEY (id)
);

其中:changeset 需要指定两个参数 [author]:[id]。这里默认生成的是 hp:1663121484082-1,author是hp,id是时间戳加一个编号。可以修改为有意义的描述,比如数据库修改作者,对应数据库版本等。

将 application.properties 文件中的 changelog 路径修改为:

spring.liquibase.change-log=classpath:db/changelog/2022/09/14-01-changelog.sql

这样应用启动时便可以自动生成 person 数据表了。这和 JPA 自动生成数据表的结果一样,只是我们得到了中间产物:changelog,可以用来进行数据库迁移等操作。

差值 changelog

当数据库有迭代升级时,我们也得将升级操作保存下来。还不能是重新生成一个 changelog 。而是,根据上一版本的数据库与现在的 Model 的差别自动生成 DDL 更新语句。JPA Buddy 可以方便实现这一操作。

为 Person 添加一个属性:address。

在 JPA Structure 中右键 liquibase 选择 diff-changelog。在弹窗中可以配置两个对比的持久化信息,这里选择:Model 和 DB,也即将Entity类相对数据表的更新操作保存下来。确定后会生成新的changelog文件:db/changelog/2022/09/14-02-changelog.sql,内容如下:

-- liquibase formatted sql

-- changeset hp:1663123561405-1
ALTER TABLE person
    ADD address VARCHAR(255) NULL;

-- changeset hp:1663123561405-2
ALTER TABLE person
    MODIFY address VARCHAR(255) NOT NULL;

将 application.properties 文件中的 changelog 路径修改为:

spring.liquibase.change-log=classpath:db/changelog/2022/09/14-02-changelog.sql

这样 Spring Boot 便会根据差值 changelog,将数据表更新。

每次更新数据库之后,手动生成一下差值 changelog 便可能保存数据库的所有操作记录,方便管理维护。

总结

本文介绍了 Spring Boot 集成 Liquibase 的方法,以及如何使用 JPA Buddy 插件快速完成,Liquibase changelog 文件的生成和升级。

Liquibase 在数据库版本管理方面很有用处,生成的中间件 changelog 文件在其他方面也很有用处,比如多数据源管理。这将在后续文章使用,请点赞评论和关注哦。

你可能感兴趣的:(SpringBoot学习,spring,boot,kotlin,mysql)