SpringBoot集成flyway进行MySQL数据库版本控制

Flyway是什么

Flyway是一个数据库版本管理工具,可以非常简单的将数据库的schema从一个版本迁移到另外一个版本,并且支持MySql,Oracle,Postgre等多种关系型数据库。主流的数据库都能够完美支持

为什么用Flyway

在项目或产品研发过程中,很难一开始就把业务理清楚,把代码逻辑和数据库表设计好,因此代码和数据表也会在迭代周期内不断迭代。我们都习惯使用SVN或者Git来对代码进行版本管理,主要是为了解决多人开发代码冲突和版本回退的问题。其实,数据库的变更也需要版本控制,在日常开发和环境部署中,我们经常会遇到下面的问题:

  • 在开发环境部署程序发现报错,定位是自己写的SQL脚本忘了在当前环境执行导致;
  • 从Git上新down下来的代码运行报错,定位发现是其他同事修改了的SQL脚本没有在当前环境执行导致;
  • 每次发布包都需要发布SQL文件包和应用程序的版本包;
  • 线上环境部署报错,发现是运维没有按照你投产文档里面说明的SQL脚本执行顺序操作执行导致;
  • 流水线可以自动化部署程序,但是SQL脚本还是需要手动执行或者流水线执行SQL脚本配置比较繁琐;
  • 其他场景…

有了Flyway,这些问题都可以轻松的解决。Flyway可以对数据库进行版本管理,可以自动执行SQL,能快速有效地用于迭代数据库表结构,并保证部署到测试环境或生产环境时,数据表都是保持一致的;说白了就是flyway工具可以像Git管理不同人的代码那样,管理不同人的sql脚本,从而做到数据库同步。

Flyway工作流程

1、项目启动,应用程序完成数据库连接池的建立后,Flyway自动运行。

2、当 Flyway 连接数据库中的 schema 后,会先检查是否已存在 schema_version 表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息。

3、flyway在升级数据库的时候,会检查已经执行过的版本对应的脚本是否发生变化,包括脚本文件名,以及脚本内容。如果flyway检测到发生了变化,则抛出错误,并终止升级,比如第一个人新增了一个字段,并且项目启动,falway执行了,而后一个人在前面这个人写的脚本上面有所改动,这样就会抛出错误

4、如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。

Flyway主要就是通过迁移(Migration)来对数据库进行版本的控制,对于Flyway而言在数据库上的所有操作都可以称之为迁移;Flyway有两种迁移方式:版本化迁移(Versioned Migration)和可重复的迁移(Repeatable Migration)

首次使用falway升级的时候,会在数据库新增一个表,名为:flyway_schema_history

这张表记录了每一次升级的记录,包括已经执行了哪些脚本,脚本的文件名,内容校验和,执行的时间和结果。

由于 schema_version 表中记录了迁移的版本号,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行。

若执行脚本报错,比如数据表id要求唯一,这时候执行flyway migrate会报错,schema_version表里头最新的一个脚本的success字段就会为0,代表失败。

在SpringBoot项目使用Flyway
添加依赖
<dependency>
 <groupId>org.flywaydb</groupId>
 <artifactId>flyway-core</artifactId>
 <version>9.0.4</version>
</dependency>
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
</dependency>
application配置

搞定了Flyway的依赖后,修改一下SpringBoot的application.yml或application.xml配置。

spring:
 datasource:
 url: jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8
 username: root
 password: tiger 
 flyway:
 enabled: true
 # 禁止清理数据库表
 clean-disabled: true
 # 如果数据库不是空表,需要设置成 true,否则启动报错
 baseline-on-migrate: true
 # 与 baseline-on-migrate: true 搭配使用
 baseline-version: 0
 locations: 
 - classpath:db/migration/mysql(根据个人情况设置)

注意事项:如果 flyway 不是项目初期引入,而是在数据库已有表的情况下引入时必须设置 baseline-on-migrate: true,设置该配置启动项目后,flyway 就会在数据库中创建 flyway_schema_history 表,并且会往该表中插入一条 version = 1 的建表记录,如果迁移数据有 V1__ 开头的文件,扫描文件会忽略该文件不执行迁移,进而可能引发其他迁移数据出错的问题。

创建SQL文件

在src/resources下创建 db/migration目录,在其中创建对应的SQL文件,其中又分为不同的文件类型,基于约定由于配置的原则,通过文件命名方式进行区分

截图.png Flyway不限定脚本里面的内容,但是对脚本文件的名称有一定的要求,基于约定由于配置的原则,不同的类型通过文件命名方式进行区分。

总结如下:

版本迁移(Versioned Migrations)以V开头,只会执行一次;

回退迁移(Undo Migrations)以U开头,执行一旦发生破坏性更改,就会很麻烦,项目中一般不用;可重复执行迁移(Repeatable Migrations)以R开头,每次修改后都会重新执行。

可重复运行的SQL,则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。比如,RaddTable.sql,Rupdate_user.sql。

版本号需要唯一,否则Flyway执行会报错;如果V__脚本.sql,已经执行过了,不能修改里面的内容,再次执行Flyway就会报错。R——脚本.sql,如有变化可以执行多次。

V开头的SQL执行优先级要比R开头的SQL优先级高。

image.png 版本号和版本描述之间,使用两个下划线分隔。

版本描述之间,使用一个下划线分隔单词。

如下,我们准备了三个脚本,分别为:

1、V2020.00.000_1__create_table.sql,代码如下,目的是创建一张表,且只执行一次

CREATE TABLE `test_flyway_table` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
 `time` datetime NOT NULL COMMENT '创建时间',
 PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、V202001.00.000_2__insertTable.sql,代码如下,目的是往表中插入一条数据,且只执行一次

INSERT INTO `test_flyway_table` VALUES ('1', '2021-06-28 17:48:48');

3、R__addTable.sql,代码如下,目的是每次启动如果有变化,则执行一次

update `test_flyway_table` set time = '2021-09-23 17:48:48' where id =1;
运行测试

按照上面配置完成,已经足够我们开始运行了,此时,我们第一次启动项目,如果配置没有错误,运行截图如下:

image.png 此时,我们刷新数据库,可以看到Flyway的历史记录表已经生成并插入了三个版本的记录:

image.png 而且,表也已经创建好了并有一条数据:

image.png 此时不做任何改变,重启程序,日志如下

image.png 如果我们修改V202001.00.000_2__insertTable.sql脚本,重启程序,就会报错,提示信息如下:

Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 202001.00.000.2
-> Applied to database : 1190158040
-> Resolved locally: 843339817. Either revert the changes to the migration, or run repair to update the schema history.

如果我们修改R__addTable.sql脚本,重启程序,脚本会再次执行,并且Flyway的历史记录表也会增加本次执行的记录。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值