场景
Git/ SVN 是代码界的版本控制工具,那么,Flyway 就是一款数据库界的版本控制工具,
它可以记录数据库的变化记录。可能很多公司都是通过人工去维护、同步数据库脚本,
但经常会遇到疏忽而遗漏的情况,举个简单的例子:
我们在开发环境对某个表新增了一个字段,而提交测试时却忘了提交该 SQL 脚本,导致出现 bug 而测试中断,
从而影响开发、测试的工作效率。有了 Flyway,我们可以按版本约定,统一管理所有的 SQL 脚本变更,
在所有环境自动同步数据库,而无需人为手工控制,再也不用担心因数据库不同步而导致的各种环境问题。
官网:Homepage - Flyway
下面记录在SpringBoot项目中集成Flyway的过程。
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
实现
1、首先搭建SpringBoot项目并配置连接Mysql的依赖和配置文件,然后pom文件中添加flyway的依赖
<!-- flyway sql版本管理 --><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>7.10.0</version></dependency>
只需添加以上依赖即可,这里示例的完整依赖为
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--MySQL驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--MyBatis整合SpringBoot框架的起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.1</version></dependency><!-- flyway sql版本管理 --><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>7.10.0</version></dependency></dependencies>
2、然后在yml中添加flyway的相关配置
放在spring节点下
配置的内容为
flyway:#是否启用enabled: true# 可以支持多个location, 用','隔开locations: classpath:db/migration# 是否允许无序的迁移,默认falseout-of-order: false# 是否创建元数据表validate-on-migrate: true# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是false 理论上作为默认配置是不科学的clean-disabled: true# 如果数据库不是空表,需要设置成 true,否则启动报错baseline-on-migrate: true# 版本控制日志表,默认flyway_schema_history,不同系统建议修改数据# table: flyway_schema_history
3、上面配置的locations即为sql文件的存放位置,这里也是默认位置,可自由配置。
这里的脚本sql的命名规则是
V + 版本号(版本号的数字间以”.“或”_“分隔开) + 双下划线(用来分隔版本号和描述) + 文件描述 + 后缀名
注意这里的双下划线来分割版本号和文件描述。
示例:
V20230710_1__init.sql
比如这里初始化数据库的sql这样命名,代表执行初始化数据的操作,比如建表或插入基础数据等。
可以在Navicat等客户端软件中直接将基础库导出为sql并重命名。
将上面的sql放到resource目录下新建的db目录下的migration目录下
4、先执行初始化基础库的sql,这里启动项目如果没有报错并能看到以下执行成功的提示
此时查看数据库,会新建表flyway_schema_history表,这是版本记录表。
并且验证init的sql文件已经执行成功。
假如我们要修改其中某个表,比如给user表添加一个字段。
首先通过Navicat等软件修改本地表添加字段
在Navicat中修改表字段可以直接在SQL预览中看到执行操作的sql。
比如这里新增address字段的SQL预览为
ALTER TABLE `test`.`user`ADD COLUMN `address` varchar(255) NULL AFTER `pass`;
再新建V20230710_2__add_address_to_user.sql文件,将上面的sql内容复制进来。
此时代表版本2的更改。
重启项目,查看日志,当前版本执行到2
并且历史记录包中记录也新增
本地将address字段删除后,重启项目后会发现会执行版本2的添加字段的操作。
5、遇到的坑
SpringBoot中集成Flyway启动时提示:
Flyway failed to initialize: none of the following migration scripts locations could be found:
仔细核对配置与目录均正确。
报错是因为在IDEA新建目录时直接使用db.migration创建,会被认定为一个目录,
应该在resource下先新建db再在db下新建migration目录。
另外要注意如果发现目录下的sql没有执行,一定要注意sql文件的命名格式,尤其是使用双下划线来区分版本号和描述。