Flyway 数据库版本管理 | 专业解决方案

前言

目前很多公司都是通过人工去维护、同步数据库脚本,但经常会遇到疏忽而遗漏的情况,同时也是非常费力耗时

比如说我们在开发环境对某个表新增了一个字段,而提交测试时却忘了提交该 SQL 脚本,导致出现 bug 而测试中断,从而影响开发、测试的工作效率

我们可以使用 Git/ SVN 等工具进行代码的版本控制,同时,数据库也有对应的版本控制工具,可以记录数据库的变化记录

Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。Flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置,Migrations 可以写成 SQL 脚本,也可以写在 Java 代码中,不仅支持 Command Line 和 Java API,还支持 Build 构建工具和 Spring Boot 等,同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等

官网首页:Homepage - Flyway (flywaydb.org)

特性

普通 SQL:纯 SQL 脚本(包括占位符替换)没有专有的 XML 格式,没有锁定

无限制:使用 Java 代码来进行一些高级数据操作

零依赖:只需运行在 Java6(及以上)和数据库所需的 JDBC 驱动

约定优于配置:迁移时,自动查找系统文件和类路径中的 SQL 文件或 Java 类

高可靠性:在集群环境下进行数据库升级是安全可靠的

云支持:完全支持 Microsoft SQL Azure, Google Cloud SQL & App Engine、Heroku Postgres 和 Amazon RDS

自动迁移:使用 Flyway 提供的 API,让应用启动和迁移同时工作

快速失败:损坏的数据库或失败的迁移可以防止应用程序启动

数据库清理:在一个数据库中删除所有的表、视图、触发器,而不是删除数据库本身

原理

当 Flyway 连接数据库中的 schema 后,会先检查是否已存在  flyway_schema_history  表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息

当  flyway_schema_history  存在后,Flyway 会扫描文件系统或应用中的 classpath 目录的数据迁移文件,然后根据它们的版本号进行按序迁移,如下图:

image.png

由于 flyway_schema_history 表中记录了迁移的版本号,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行

实战

数据库:MySQL 8.0

官方文档:Quickstart - API - Flyway - Product Documentation (red-gate.com)

Maven

首先新建 Maven 项目

image.png

添加依赖
        <!-- flyway --><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>5.2.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.15</version></dependency>
创建迁移

首先我们需要创建迁移文件 src/main/resources/db/migration

然后配置数据库迁移文件,实施第一次迁移 src/main/resources/db/migration/V1__Create_person_table.sql

注意:V1 后面是两个下划线,必须是这样的格式

create table PERSON
(ID   int          not null,NAME varchar(100) not null
);

然后配置主启动函数

public class App {public static void main(String[] args) {String url = "jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8";String user = "root";String password = "111111";Flyway flyway = Flyway.configure().dataSource(url, user, password).load();// 创建 flyway_schema_history 表
//		flyway.baseline();// 删除 flyway_schema_history 表中失败的记录
//		flyway.repair();// 检查 sql 文件
//		flyway.validate();// 执行数据迁移flyway.migrate();// 删除当前 schema 下所有表
//		flyway.clean();}}
执行程序

执行 App 程序

注:我们需要提前创建空数据库 flyway,如果 flyway 不是项目初期引入,后面会给出解决方案

image.png

然后我们可以看到现在已经创建了 flyway_schema_history 表和 PERSON 表,数据已经成功迁移到指定数据库中
image.png

现在如果系统升级,需要做数据迁移时,我们只需在 db/migration 目录下再放置新版本的 sql 文件即可

现在我们配置第二次迁移,创建文件 src/main/resources/db/migration/V2__Add_people.sql

insert into PERSON (ID, NAME)
values (1, 'Axel');
insert into PERSON (ID, NAME)
values (2, 'Mr. Foo');
insert into PERSON (ID, NAME)
values (3, 'Ms. Bar');

然后执行 App ,就可以看到如下执行成功

image.png

SpringBoot

下面整合 flyway 到 springboot

添加依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId></dependency>

配置 application.yml

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: 111111flyway:enabled: true# 禁止清理数据库表clean-disabled: true# 如果数据库不是空表,需要设置成 true,否则启动报错baseline-on-migrate: true# 与 baseline-on-migrate: true 搭配使用baseline-version: 0# 不配置默认为 db/migration 目录locations:- classpath:db/migration/mysql

如果 flyway 不是项目初期引入,而是在数据库已有表的情况下引入时必须设置 baseline-on-migrate: true(此时没有配置 baseline-version: 0),设置该配置启动项目后,flyway 就会在数据库中创建 flyway_schema_history 表,并且会往该表中插入一条 version = 1 的建表记录,如果迁移数据有 V1__ 开头的文件,扫描文件会忽略该文件不执行迁移,进而可能引发其他迁移数据出错的问题

因为没有执行 V1__ 开头的文件,那么库中就不创建 PERSON 表,在迁移 V2 插入数据时就会插入失败

所以出现如上问题后,我们可以先删除flyway_schema_history  表,然后配置文件中设置  baseline-version: 0 即可,或者说修改数据迁移文件名称也是可行的

其他问题

版本问题

SpringBoot 2.4.4 集成 flyway 版本 7.1.1 (Oracle12.1.0.2 标准版可以执行,企业版不行)

SpringBoot 2.6.0 集成 flyway 版本 8.0.4 (Oracle12.1.0.2 都可以执行)

SQL 脚本命名规范

Prefix+Version+Separator+Description+Suffix

Prefix 前缀:V 代表版本迁移,U 代表撤销迁移,R 代表可重复迁移

Version 版本号:版本号通常 . 和整数组成

Separator 分隔符:固定由两个下划线 __ 组成

Description 描述:由下划线分隔的单词组成,用于描述本次迁移的目的

Suffix 后缀:如果是 SQL 文件那么固定由 .sql 组成,如果是基于 Java 类则默认不需要后缀

参考链接

  • 数据库/SQL 版本管理工具选型指北:Flyway、Liquibase、Bytebase、阿里 DMS
  • java - Spring Boot 集成 Flyway,数据库也能做版本控制
  • Flyway 简单入门教程 - 掘金 (juejin.cn)
  • SpringBoot 集成 flyway - 简书 (jianshu.com)
  • Flyway 快速上手教程 - 简书 (jianshu.com)

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/233802.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python+pytest接口自动化(4)-requests发送get请求

python中用于请求http接口的有自带的urllib和第三方库requests&#xff0c;但 urllib 写法稍微有点繁琐&#xff0c;所以在进行接口自动化测试过程中&#xff0c;一般使用更为简洁且功能强大的 requests 库。下面我们使用 requests 库发送get请求。 requests库 简介 request…

开源生成式AI初创平台together.ai,获7.3亿元融资

11月30日&#xff0c;开源生成式AI平台Together AI在官网宣布&#xff0c;获得1.025亿美元&#xff08;约7.3亿元&#xff09;A轮融资。本次由凯鹏华盈 (Kleiner Perkins) 领投&#xff0c;英伟达、Emergence Capital、 NEA、Prosperity 7、Greycroft等跟投。 公开资料显示&am…

LeetCode(34)有效的数独【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 36. 有效的数独 1.题目 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗…

c MJPG(1)

.读取量化表&#xff0c;全局参数&#xff0c;霍夫曼表&#xff0c;恢复表编码&#xff0c;现在只是实现思路。 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sy…

1.网络编程基础知识 - 基础概念、TCP网络通信、UDP网络通信

网络编程 文章目录 网络编程一、概念1.1 网络1.2 IP地址1.2.1 IPv4 介绍1.2.2 IPv6 介绍1.2.3 查看IP地址 1.3 域名和端口1.4 网络协议1.5 TCP与UDP1.6 InetAddress类1.7 Socket 二、TCP网络通信编程2.1 介绍2.2 案例2.2.1 字节流编程案例12.2.2 字节流编程案例22.2.3 字符流编…

项目终验的exce表格缩放,排版等经常使用

xxx个项目的验收资料 1.申请表等等很多信息 需求&#xff1a;放在一页内等办法 上述文档&#xff0c;在excel表格打印预览中都是在两页中&#xff0c;很难调节&#xff0c;这个时候采用wps专业版本即可。 wps排版经常使用的功能如下&#xff1a; 经常使用的是 1.把所有列打印…

骨传导与入耳式耳机哪种音质好?骨传导与入耳式耳机有什么区别?

由于骨传导耳机和入耳式耳机的传声原理不同&#xff0c;入耳式耳机的音质要更好一些&#xff01; 想要了解骨传导耳机和入耳式耳机哪种音质好&#xff0c;首先就要了解骨传导耳机和入耳式耳机的传声原理有什么区别&#xff1f; 一、骨传导耳机和入耳式耳机有什么区别 1、传声…

MySQL与其他数据库产品的比较,优势在哪里?

作为数据库管理领域的博主作家&#xff0c;我深知数据库在软件开发和数据管理中的重要性。在当今众多的数据库产品中&#xff0c;MySQL作为一种流行的开源关系型数据库管理系统&#xff0c;具有许多优势和特点。下面&#xff0c;我将通过对与其他数据库产品的比较以及MySQL的优…

【JavaEE】线程安全与线程状态

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

牛客算法心得——abb(dp)

大家好&#xff0c;我是晴天学长&#xff0c;传智杯的题&#xff0c;我准备写一个题解&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .abb leafee 最近爱上了 abb 型语句&#xff0c;比如“叠词词”、…

深入探索Maven:优雅构建Java项目的新方式(二)

Meven高级 1&#xff0c;属性1.1 属性1.1.1 问题分析1.1.2 解决步骤步骤1:父工程中定义属性步骤2:修改依赖的version 1.2 配置文件加载属性步骤1:父工程定义属性步骤2:jdbc.properties文件中引用属性步骤3:设置maven过滤文件范围步骤4:测试是否生效 1.3 版本管理 2&#xff0c;…

Xpath定位文本中含有空格的元素

可以使用XPath中的normalize-space函数来定位文本中含有空格的元素。主要包含normalize-space(.)、normalize-space(text())两种用法&#xff1a; 使用 normalize-space(.) 的例子&#xff1a; <root><element>Hello, world!</element> </root>在上述…