一、背景二、主流方案
✌Flyway VS Liquibase 三、Flyway中常见概念
Schema History TableMigrationVersioned MigrationUndo MigrationRepeatable Migrationbaseline 四、在 Spring Boot 项目中引入 Flyway
引入Flyway配置配置项添加 sql 脚本非空数据库处理其他问题
一、背景如果你还在每个版本发布时单独分发数据库变动脚本,甚至简单粗暴的将开发库直接导出并导入生产环境,建议一起来读一下这篇文章。
二、主流方案这个一般来说就两个: Flyway 和 Liquibase ,如有更优秀的开源技术请大家留言补充。
✌Flyway VS Liquibase感兴趣的可以看一下这篇文章,我的总结如下:
- Flyway 和 Liquibase 都支持数据库重构和版本控制所需的所有功能,并且这两个工具都可以完美集成在 Maven 或 Gradle 构建脚本以及 Spring Boot 生态系统中。 Flyway 使用 SQL 来定义数据库更改,因此您可以定制 SQL 脚本以与 Oracle 或 PostgreSQL 等数据库很好地配合使用。另一方面,Liquibase 不使用 SQL ,而是通过使用 XML , YAML 或 JSON 来定义数据库更改来引入抽象层。因此,Liquibase 更适合用于拥有多数据源的应用中。但是,如果想完全控制 SQL ,Flyway 是首选工具,因为我们可以使用定制的 SQL 甚至 Java 代码修改数据库。Flyway 相比 Liquibase 在社区更活跃。
三、Flyway中常见概念简单来说:
面向 SQL,选择 Flyway不面向 SQL,选择 Liquibase
Flyway 中的概念可查阅官方文档,这里挑选一些重要的进行简单介绍。
Schema History TableFlyway 对数据库进行版本控制的方式,是在指定数据库中创建一张表,即 Schema History Table(默认为 flyway_schema_history),记录由 Flyway 所执行的 sql 脚本状态。 Migration
在 Flyway 中,所有对数据库的变动,均称为 migration(译:迁移),migration 可以是 SQL 文件,也可以是 Java 类。默认的查找 migration 的路径是 classpath:db/migration,也就是说对应 SQL 文件可以放置在 src/main/resources/db/migration 下,Java 类可以放置在 src/main/java/db/migration 下。Migration 可以是仅执行一次的(versioned),也可是重复执行的(repeatable)。 Versioned Migration
Versioned migration 包括版本号、描述和校验值(checksum,自动计算),命名方式如下:
其中版本号必须是全局(在一个 Schema History Table 里维护)唯一,默认情况下(可通过参数调整)版本号只能增加,不能在已经执行了高版本的 migration 之后再执行低版本的 migration。
版本号可以是数字加 . 的形式,例如下面都是合法的版本号:
1 001 5.2 2013.01.15.11.35.56
checksum 用来检查 migration 在执行过后是否发生了变化,如果发生了变化,会导致这个版本以及后续版本的 migration 无法执行。
flyway_schema_history表举例:
Versioned migration 中,还有一种特殊的类型 undo migration,可为对应版本的常规 versioned migration 进行回退操作(但这玩意是收费的),命名方式如下:
Repeatable Migration
Repeatable migration 包括描述和校验值,没有版本号信息,会在每次校验值(migration 内容变化会导致校验值变化)发生变化时重复执行,命名方式如下:
Repeatable migration 会在所有的 versioned migration 都执行过后再进行执行,Repeatable migration 内部按照其文件名中描述(description)部分的顺序执行。在 repeatable migration 中需保证其中内容可重复执行,比如在 DDL 中使用 CREATE OR REPLACE。
baseline
当数据中已经存在内容时,再引入 Flyway,可通过 baseline 设定一条基线。
如果想将基线之前的数据库中表结构和数据纳入 Flyway 一同管理,可以将基线前的状态导出成数据库脚本,通过 versioned migration 添加至 flyway 中,并设定 baselin version,Flyway 会忽略基线版本号(包括)之前版本的所有 migration。如果不想管理基线之前的数据库状态(比如多模块或应用操作同一数据库,互相之间不受影响),可以只告诉 Flyway 执行 migration 的时候是存在基线的,这样就不会报出数据库非空的异常。
四、在 Spring Boot 项目中引入 Flyway
在 Spring Boot 项目中,引入 Flyway 很简单,因为在 Spring Boot 的 spring-boot-autoconfigure 中包含了 Flyway 的自动配置,只要添加 flyway 的依赖即可,如下图:
Gradle方式:
implementation 'org.flywaydb:flyway-core
Maven方式:
配置配置项org.flywaydb flyway-core
spring.flyway.enabled:是否开启 flyway,默认就是开启的spring.flyway.encoding:flyway 字符编码spring.flyway.locations:sql 脚本的目录,默认是classpath:db/migration,如果有多个用 , 隔开spring.flyway.clean-disabled:表示是否要清除已有库下的表,如果执行的脚本是 V1__xxx.sql,那么会先清除已有库下的表,然后再执行脚本,这在开发环境下还挺方便,但是在生产环境下就要命了,而且它默认就是要清除,生产环境一定要自己配置设置为 true。spring.flyway.table:配置数据库信息表的名称,默认是flyway_schema_history。 添加 sql 脚本
引入 Flyway 之后,再启动应用时,会在默认路径 classpath:db/migration 查找 sql 脚本,如果没找到会报错,影响应用启动。
非空数据库处理当在一个已有项目中引入 Flyway 后,数据库中可能已经存在了一些表和初始化数据,此时按照上述方式引入 Flyway 时会提示如下异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Found non-empty schema(s) `demo` but no schema history table. Use baseline() or set baselineonMigrate to true to initialize the schema history table.
此时需要设定 spring.flyway.baseline-on-migrate=true 参数,告诉 Flyway 在执行 sql 脚本之前,数据库是非空状态。
其他问题
SQL 报错
通过 Spring Boot 自动执行 migration 时要注意,一旦 migration 执行失败,应用启动会终止。出现 migration 执行失败时,需要将 Schema History Table 表中的失败记录处理掉,才能再次执行 migration,否则应用会一直无法启动。
out-of-order
多人开发时,可能会出现 A 写了 V1 脚本,B 写了 V2 脚本,B 的代码先合并进去了,V2 脚本先执行了,此时 A 的 V1 脚本受版本号只能增加的要求不能再执行。
这种情况可以通过将 spring.flyway.out-of-order 设置为 true 来暂时取消这个限制,不过还是强烈建议 A 将 V1 脚本版本号改为 V3。
【前端-开发环境】使用NVM实现不同nodejs版本的自由切换(NVM完整安装使用手册)
【前端-NPM私服】内网使用verdaccio搭建私有npm服务器
【前端-IE兼容】Win10和Win11使用Edge调试前端兼容IE6、IE7、IE8、IE9、IE10、IE11问题
【工具-Shell脚本】java程序产品包模板-linux和windows通用shell启动停止脚本(无需系统安装Java运行环境)
【工具-Nginx】Nginx高性能通用配置文件-注释版-支持防刷限流、可控高并发、HTTP2、防XSS、Gzip、OCSP Stapling、负载、SSL
【工具-WireShark】网络HTTP抓包使用教程
【后端-maven打包】通过profile标签解决同时打jar包 war包需求
【后端-SpringCache】基于Spring Cache封装一个能够批量操作的Redis缓存记录下踩坑历程(pipeline或mget封装)
【后端-SkyWalking】SkyWalking前后端开发环境搭建详细教程步骤-6.x/7.x/8.x版本通用-插件二次开发利器(一)
✨欢迎为耿直少年点赞、关注、收藏!!!



