目录
1. 前言
2. Flyway 简介
3. Flyway 规则
4. Spring Boot 集成 Flyway
4.1 Flyway 依赖
4.2 Flyway 配置
4.3 Flyway 迁移实战
4.3.1 创建初始化脚本
4.3.2 创建变更脚本
5. Flyway最佳实践
6. 总结
1. 前言
我们都知道,Git/SVN 是代码界的版本控制工具,那么,Flyway 就是数据库界的版本控制工具,它可以记录数据库的变化记录。
可能很多公司都是通过人工去维护、同步数据库脚本,就比如我现在所在的公司。但经常会遇到疏忽而遗漏的情况,举个简单的例子:
我们在开发环境对某个表新增了一个字段,而提交测试时却忘了提交该 SQL 脚本,导致出现bug而测试中断,从而影响开发、测试工作效率。严重点的话,如果是在生产环境才发现问题,将会是重大线上事故,年终奖就别考虑了~
而有了 Flyway,我们可以按版本约定,统一管理所有的 SQL 脚本变更,在所有环境自动同步数据库,而无需人为手工控制,再也不用担心因数据库不同步而导致的各种环境问题了。绩效也杠杠滴 :)。
2. Flyway 简介
Flyway 是一个简单开源数据库版本控制器(约定大于配置),它支持 SQL、Java API 和命令行的运行方式,还提供一系列的插件支持(Maven、Gradle、ANT等)。
主要支持的命令:
- Migrate(迁移)
- Clean(清理所有配置的对象)
- Info(显示迁移状态和细节)
- Validate(验证迁移规则)
- Undo(撤消最近的迁移)
- Baseline(建立基线)
- Repair(修复迁移历史表)
Flyway 大受欢迎是因为它具有以下优点:
- 简单 非常容易安装和学习,同时迁移的方式也很容易被开发者接受。
- 专一 Flyway 专注于搞数据库迁移、版本控制而并没有其它副作用。
- 强大 专为连续交付而设计。让 Flyway 在应用程序启动时迁移数据库。
官方网站:https://flywaydb.org/
3. Flyway 规则
Flyway 是如何比较两个 SQL 文件的先后顺序的呢?它采用 左对齐原则,缺位用0代替。举几个例子:
1.0.0.1 比 1.0.0 版本高。
1.0.10 比 1.0.9.4 版本高。
1.0.0_1 比 1.0.0 版本高。
1_0_0_1 比 1_0_0 版本高。
1.0.10 和 1.0.010 版本号一样高,这是因为每个版本号部分的前导 0 会被忽略。
Flyway 将 SQL 文件分为 Versioned 、Repeatable 和 Undo 三种:
- Versioned 用于版本升级,每个版本有唯一的版本号并只能执行一次。
- Repeatable 可重复执行,当 Flyway 检测到 Repeatable 类型的 SQL 脚本的 checksum 有变动,Flyway 就会重新执行该脚本,它并不用于版本更新,这类的 migration 总是在 Versioned 执行之后才被执行。
- Undo 用于撤销具有相同版本的版本化迁移带来的影响。但是该回滚过于粗暴,过于机械化,一般不推荐使用。一般建议使用 Versioned 模式来解决。
这三种的命名规则如下图:
- Prefix 可配置,前缀标识,默认值 V 表示 Versioned, R 表示 Repeatable, U 表示 Undo。
- Version 标识版本号, 由一个或多个数字构成,数字之间的分隔符可用点 . 或下划线 _。
- Separator 可配置,用于分隔版本标识与描述信息,默认为两个下划线 __。
- Description 描述信息,文字之间可以用下划线 _ 或空格 分隔。
- Suffix 可配置,后续标识,默认为 .sql。
4. Spring Boot 集成 Flyway
Spring Boot 提供了对 Flyway 的自动配置,使我们可以开箱即用 Flyway 进行数据库版本控制。
本文演示环境:
- JDK 1.8
- Spring Boot 2.7.18
- MySQL 8.0
4.1 Flyway 依赖
spring-boot-dependencies 默认提供了对 Flyway 的版本管理,这里仅展示核心依赖:
org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-jdbccom.mysql mysql-connector-jruntime org.flywaydb flyway-coreorg.flywaydb flyway-mysql4.2 Flyway 配置
Spring Boot 默认提供了对 Flyway 的自动配置:
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
所以,在Spring Boot 项目中,我们仅仅只要提供对应的配置参数即可:
# 数据库配置 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false spring.datasource.username=root spring.datasource.password=root # 启动flyway migration, 默认为true spring.flyway.enabled=true # flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。 spring.flyway.clean-disabled=true # SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migration spring.flyway.locations[0]=classpath:db/migration # metadata 版本控制历史表 默认 flyway_schema_history spring.flyway.table=flyway_schema_history # 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令 # 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。 spring.flyway.baseline-on-migrate=true
Flyway 也是遵循 约定大于配置 的思想,更多 Flyway 的参数配置可以参考这个类:
org.springframework.boot.autoconfigure.flyway.FlywayProperties
4.3 Flyway 迁移实战
4.3.1 创建初始化脚本
首先,创建三个迁移脚本,相当于项目初始化:
- V1.0.0_1__create_user.sql
- V1.0.0_2__create_role.sql
- R__init_data.sql
请注意命名规则。
具体 SQL 脚本内容就不贴上来了,完整的示例代码已提交 Gitee:
https://gitee.com/haitao9481/springboot-flyway-demo
1)首次启动
从启动日志可以看出,已经迁移了3个脚本,并将当前版本更新到了 V1.0.0.2:
查看数据库,Flyway 历史表和业务表及数据都已经创建:
2)不修改再次启动
在不修改任何代码的情况下再次启动:
可以看到成功验证了 3 个迁移脚本,打印了当前版本号。因为当前没有比1.0.0.2更大的版本号,所以不会进行迁移。
4.3.2 创建变更脚本
我们再新增一个 SQL 脚本,相当于项目版本迭代过程中产生的 SQL 变更:
- V1.0.1_1__alert_user.sql
对user表新增一个字段:create_time。
我们再次启动下:
成功迁移,当前版本来到了 V1.0.1.1。
5. Flyway最佳实践
通过上面的介绍相信你很快就会使用 Flyway 进行数据库版本控制了。这里总结了一些在实际开发中的使用经验:
- 生产环境请务必设置 spring.flyway.clean-disabled=true。
- 尽量避免使用 Undo 模式。
- 开发版本号尽量根据团队来进行多层次的命名避免混乱。比如 Vx.y.z_{sequence}__{create|alert|feature|fix}_Description_Timestamp.sql ,这种命名可以获取更多脚本相关功能的信息。
- 多个系统公用一个数据库 schema 时配置 spring.flyway.table 为不同的系统设置不同的 metadata 表名而不使用缺省值 flyway_schema_history。
6. 总结
我们对 Flyway 数据库版本migration工具进行了介绍,并在Spring Boot应用中集成。Flyway 使用简单、自动化、开箱即用,这将大大规范我们的数据库管理,提高生产效率。
本文完整示例代码已上传 Gitee:
https://gitee.com/haitao9481/springboot-flyway-demo
如果您觉得本文不错,欢迎转发分享,原创不易,Hyatt需要您的鼓励。
- V1.0.1_1__alert_user.sql
还没有评论,来说两句吧...