SpringBoot数据库管理 - 用flyway对数据库管理和迁移
上文介绍了Liquibase,以及和SpringBoot的集成。除了Liquibase之外,还有一个组件Flyway也是经常被使用到的类似的数据库版本管理中间件。本文主要介绍Flyway, 以及SpringBoot集成Flyway。@pdai
知识准备
需要了解Flyway和要解决的问题,以及一些基础概念,比如变迁(migrations),常用命令(commands)等。
什么是Flyway? 要解决什么问题?
Flyway是一款数据库迁移(migration)工具。简单点说,就是在你部署应用的时候,帮你执行数据库脚本的工具。Flyway支持SQL和Java两种类型的脚本,你可以将脚本打包到应用程序中,在应用程序启动时,由Flyway来管理这些脚本的执行,这些脚本被Flyway称之为migration。
PS: 本质上和liquibase机制一致。
按照verion的顺序(和数据库中的更新记录对比,找到未更新的),更新如下

更新记录如下

Flyway中的变迁(migrations)
对于Flyway,对数据库的所有更改都称为变迁(migrations),等同于liquibase中的changeset。
在Flyway中变迁(migrations)定义的更细,包含如下三种:
- 版本变迁(Versioned Migrations): 每个版本执行一次,包含有版本、描述和校验和;常用于创建,修改,删除表;插入,修改数据等
- 撤销变迁(Undo Migrations): 版本变迁(Versioned Migrations)的反操作。
- 可重复变迁(Repeatable Migrations): 可以执行多次,包含描述和校验和(没有版本);主要用于视图,存储过程,函数等
这三种类型对应的格式如下:

- 前缀: V 代表版本变迁(Versioned Migrations), U 代表撤销变迁(Undo Migrations), R 代表可重复变迁(Repeatable Migrations)
- 版本号: 唯一的版本号,比如V1.0.1
- 分隔符: __ (两个下划线)
- 描述信息: 描述信息
- 后缀: .sql
(PS:撤销变迁(Undo Migrations)在收费版本中)
Flyway中常用命令
Flyway中的常用commands有哪些?什么含义?
Migrate: 是Flyway工作流的核心。它将扫描文件系统或类路径以查找可用的Migrate。它将把它们与已应用于数据库的Migrate进行比较。如果发现任何差异则迁移数据。

Clean: 清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用;(PS:不能用在product环境)

Info: 用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本;

Validate: 验证以及apply的Migrations是否有变更,默认开启的;原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

Undo: Migrate的反操作, 即回滚操作,这是收费功能

BaseLine:对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以应用到已有表结构的数据库中也可以实现添加Metadata表。

Repair:repair操作能够修复metaData表,该操作在metadata出现错误时很有用

简单示例
这里主要介绍基于SpringBoot集成flyway来管理数据库的变更。
POM依赖
Maven 包的依赖,主要包含mysql驱动, JDBC(这里spring-boot-starter-data-jpa包含了jdbc包,当然直接引入jdbc包也行),以及flyway包。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.github.wenhao</groupId>
<artifactId>jpa-spec</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>8.5.7</version>
</dependency>
yml配置
SpringBoot AutoConfig默认已经包含了对flyway的配置,在spring.flyway配置下
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db_flyway?useSSL=false&autoReconnect=true&characterEncoding=utf8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: bfXa4Pt2lUUScy8jakXf
flyway:
enabled: true
encoding: UTF-8
# 可以支持多个location, 用','隔开
locations: classpath:db/migration
# migrate是否校验
validate-on-migrate: true
在开发时,更多的配置可以从如下SpringBoot AutoConfig中找到。

Migrate配置
这里我们准备两个Versioned Migration

- V1.0__Init_DB.sql
DROP TABLE IF EXISTS `tb_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`email` varchar(45) DEFAULT NULL,
`phone_number` int(11) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
- V1.1__Init_Data.sql
LOCK TABLES `tb_user` WRITE;
/*!40000 ALTER TABLE `tb_user` DISABLE KEYS */;
INSERT INTO `tb_user` VALUES (1,'pdai','dfasdf','suzhou.daipeng@gmail.com',1212121213,'afsdfsaf','2021-09-08 17:09:15','2021-09-08 17:09:15');
/*!40000 ALTER TABLE `tb_user` ENABLE KEYS */;
UNLOCK TABLES;
测试
启动springBootApplication, 我们可以看到如下log
2022-04-13 07:56:56.122 INFO 86030 --- [ main] o.f.c.i.database.base.DatabaseType : Database: jdbc:mysql://localhost:3306/test_db_flyway (MySQL 8.0)
2022-04-13 07:56:56.220 INFO 86030 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 2 migrations (execution time 00:00.074s)
2022-04-13 07:56:56.245 INFO 86030 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table `test_db_flyway`.`flyway_schema_history` ...
2022-04-13 07:56:56.270 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.282 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.292 INFO 86030 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema `test_db_flyway`: << Empty Schema >>
2022-04-13 07:56:56.297 INFO 86030 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema `test_db_flyway` to version "1.0 - Init DB"
2022-04-13 07:56:56.309 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: Unknown table 'test_db_flyway.tb_user' (SQL State: 42S02 - Error Code: 1051)
2022-04-13 07:56:56.309 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.309 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.310 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. (SQL State: HY000 - Error Code: 3719)
2022-04-13 07:56:56.310 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.317 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: Integer display width is deprecated and will be removed in a future release. (SQL State: HY000 - Error Code: 1681)
2022-04-13 07:56:56.317 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: Integer display width is deprecated and will be removed in a future release. (SQL State: HY000 - Error Code: 1681)
2022-04-13 07:56:56.317 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. (SQL State: HY000 - Error Code: 3719)
2022-04-13 07:56:56.317 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.318 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.333 INFO 86030 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema `test_db_flyway` to version "1.1 - Init Data"
2022-04-13 07:56:56.334 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.335 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: Table storage engine for 'tb_user' doesn't have this option (SQL State: HY000 - Error Code: 1031)
2022-04-13 07:56:56.335 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.335 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 1 rows affected
2022-04-13 07:56:56.336 WARN 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : DB: Table storage engine for 'tb_user' doesn't have this option (SQL State: HY000 - Error Code: 1031)
2022-04-13 07:56:56.337 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.337 INFO 86030 --- [ main] o.f.c.i.s.DefaultSqlScriptExecutor : 0 rows affected
2022-04-13 07:56:56.346 INFO 86030 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 2 migrations to schema `test_db_flyway`, now at version v1.1 (execution time 00:00.058s)
生成的flyway更新的记录,test_db_flyway.flyway_schema_history

已经user表结构和数据

进一步理解
通过几个问题,进一步理解。
MySQL的支持性问题
从Flyway对MySQL支持性,可以看出官方期望通过MySQL使用的大量基数获取更多的付费用户。
首先,如果你只是引入flyway-core:8.5.7的包时,会报如下错误
Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 8.0
at org.flywaydb.core.internal.database.DatabaseTypeRegister.getDatabaseTypeForConnection(DatabaseTypeRegister.java:106) ~[flyway-core-8.5.7.jar:na]
at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:76) ~[flyway-core-8.5.7.jar:na]
at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:147) ~[flyway-core-8.5.7.jar:na]
at org.flywaydb.core.Flyway.migrate(Flyway.java:124) ~[flyway-core-8.5.7.jar:na]
at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.5.3.jar:2.5.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar:5.3.9]
... 18 common frames omitted
因为找不到内置的Datebase type

所以你应该引入的包是flyway-mysql:8.5.7,而有意思的是这个包中包含的flyway-core版本是7.7.3

然后我们看下官网对MySQL的支持性,这骚操作,5.7版本还需要使用企业版。就是为了收费,折腾...。

示例源码
https://github.com/realpdai/tech-pdai-spring-demos
SpringBoot数据库管理 - 用flyway对数据库管理和迁移的更多相关文章
- SpringBoot数据库管理 - 用Liquibase对数据库管理和迁移?
Liquibase是一个用于用于跟踪.管理和应用数据库变化的开源工具,通过日志文件(changelog)的形式记录数据库的变更(changeset),然后执行日志文件中的修改,将数据库更新或回滚(ro ...
- 在SpringBoot中使用flyway进行数据库版本管理
本文大纲 flyway是什么 能帮助我们解决什么问题 springboot环境下使用flyway flyway的工作原理 一.flyway是什么 Flyway是一个开源的数据库版本管理工具,并且极力主 ...
- SpringBoot系列: 使用 flyway 管理数据库版本
Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star ...
- 转:SpringBoot系列: 使用 flyway 管理数据库版本
Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star 数 ...
- Flyway详解以及Springboot集成Flyway(转)
Flayway是一款数据库版本控制管理工具,,支持数据库版本自动升级,Migrations可以写成sql脚本,也可以写在java代码里:不仅支持Command Line和java api ,也支持Bu ...
- 数据库迁移神器——Flyway
不知道你有没有遇到过这种场景,一套代码部署在不同的环境中,随着时间的过去,各个环境代码有版本差异,代码层面可以通过不同的版本来控制,但是数据库层面经常容易忘记更新! 前言 比如刚开始环境 A 和环境 ...
- 数据库迁移Flyway
为什么需要Flyway 日常开发常常会遇到一些这样的场景 小红开发一个模块在本地数据库增加了两个字段,并且改动了dao层的代码提交到git.这时候小黄拉取了代码Run很可能报错. 如果在上线正式环境的 ...
- [转]application.properties详解 --springBoot配置文件
本文转载:http://blog.csdn.net/lpfsuperman/article/details/78287265###; # spring boot application.propert ...
- application.properties详解 --springBoot配置文件【转载】
# spring boot application.properties配置的各个属性详解 # 该示例文件作为标准提供.(官方文档 翻译过来的) # 还是花了些功夫翻译,各位如果转发,请留下本文地址, ...
随机推荐
- vue - vue基础/vue核心内容
终于算是顺利进入vue了,确实也只有学了过后才知道,之前三过vue而不学,确实是对的,现在进来了一点都不后悔,ajax.node.js.promise.webpack.git等等确实是除了三大基础外还 ...
- Go Context 原理详解
实现一个小目标 很开心的一件事,学习了一个月的后端拿到一个13k的offer,今年年底目标拿到一个30k的go方向offer. 好了回归正文,这篇文章是回答交流时一个老哥的问题,跟go的context ...
- wlile、 for循环和基本数据类型及内置方法
while + else 1.while与else连用 当while没有被关键字break主动结束的情况下 正常结束循环体代码之后执行else的子代码 """ while ...
- 2┃音视频直播系统之浏览器中通过 WebRTC 拍照片加滤镜并保存
一.拍照原理 好多人小时候应该都学过,在几张空白的纸上画同一个物体,并让物体之间稍有一些变化,然后连续快速地翻动这几张纸,它就形成了一个小动画,音视频播放器就是利用这样的原理来播放音视频文件的 播放器 ...
- 面试简历书写、Flask框架介绍与快速使用、Flask演示登录页面、用户信息页面案例
今日内容概要 面试简历编写 Flask框架介绍与安装 内容详细 1.面试简历编写 # 千万不要几个小时把简历凑出来 几天到一周 # 有没有面试机会,取决于简历写得怎么样 简历写好是第一步 # 投简历的 ...
- MongoDB是什么?非关系型数据库的优点?安装使用教程
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,由于球姐都有孩子了, ...
- unity---点击事件
点击事件 点击触发的事件脚本 脚本挂载方式 On Click() 如果点击后触发,调用Button物体下,Button_lick脚本中的func函数/func_text 结果
- 用t-SNE进行流形学习(digits数据集)
流行学习算法: 是一类用于可视化的算法,它允许进行更复杂的映射,通常也可以给出更好的可视化. t-SNE算法是其中一种. PCA是用于变换数据的首选方法,也可以进行可视化,但它的性质(先旋转然后减少方 ...
- SSH 的使用和配置
命令 ssh user@hostname -p port Windows 下首次执行这个命令会由于 Windows 默认没有运行 ssh-agent 导致无法连接,可以通过在 powershell 下 ...
- JAVA - 类的加载过程
JAVA - 类的加载过程 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化. 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象 ...