1 缘起与目的
最近遇到一个项目要部署到很多不同的地方,在每个地方升级时如何管理数据库升级脚本就成了一个叩待解决的问题。本文引入flyway工具来解决这个问题。
2 依赖
xml
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
此处笔者MySQL版本为5.7,上述版本依赖可生效。此处踩坑过程见踩坑记录。
3 yml
yml
spring:
# flyway 配置
flyway:
# 启用或禁用 flyway
enabled: false
# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。
clean-disabled: true
# SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migration {vendor}对应数据库类型,可选值 https://github.com/spring-projects/spring-boot/blob/v2.3.3.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java
locations: classpath:sql/{vendor}
# metadata 版本控制信息表 默认 flyway_schema_history
table: flyway_schema_history
# 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令
# 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。
baseline-on-migrate: false
# 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略
baseline-version: 1
# 字符编码 默认 UTF-8
encoding: UTF-8
# 是否允许不按顺序迁移 开发建议 true 生产建议 false
out-of-order: false
# 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常
validate-on-migrate: true
4 表结构
配好后依赖和yml直接启动项目会自动创建表结构。
值得一说的是checksum。可以理解为校验字符串,每次执行完sql脚本后会针对脚本生成checknum,后续如果之前执行过的脚本出现改动与前面的checknum不一致会直接报错。
4 脚本命名
命名规则如下:
V版本号__版本名.sql
例如: V2.1.5__create_user_ddl.sql
、V4.1_2__add_user_dml.sql
因为配置的baseline-version=1,所以只有1以上版本才会被执行,上图V0.0.1__base.sql是不会被执行的。上图只是为了展示命名规则。
5 踩坑记录
5.1 Unsupported Database: MySQL 5.7
笔者最开始的依赖如下:
xml
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
报错如下:
java
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'asyncBeanPriorityLoadPostProcessor' defined in class path resource [io/github/linyimin0812/async/AsyncBeanAutoConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'efpxInitQuartzJob': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysJobServiceImpl' defined in file [E:\java\project\pm2\pm_modularity\efp-plugins\target\classes\com\sdecloud\modules\quartz\service\impl\SysJobServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is 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: Unsupported Database: MySQL 5.7
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
此处笔者检索到了互联网文章 【原创】Flyway 8.2.1及以后版本不再支持MySQL?!_unsupported database: mysql 8.0-CSDN博客,阅读后笔者表示???还是去官网一探究竟吧。
-
通过官网(documentation.red-gate.com/flyway/flyw... 对MySQL支持的说明,修改依赖如下:
xml<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-mysql</artifactId> </dependency>
结果依然报错如下
csharpMySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition.
-
通过stack overflow(stackoverflow.com/questions/7... )查询发现:
(1)Flyway Community Edition 8.0.0-beta1放弃了对5年以上数据库的支持,包括MySQL 5.7 在这次提交中,MySQL的最低支持版本从5.7增加到8.0,这是在Flyway 8.0.0-beta1中引入的。目前,支持MySQL 5.7的最新社区版本是Flyway 7.15.0。
(2)从Flyway第10版(2023年10月)起,此限制不再有效。我们已经更新了Flyway,使其适用于所有支持的数据库版本,因此如果您升级到版本10,您可以访问所有支持的MySQL版本。
笔者回退到7.15.0后再无报错。即最终依赖为标题1所示。