flyway的快速入门教程
Posted Evan Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flyway的快速入门教程相关的知识,希望对你有一定的参考价值。
目录
4、添加需要运行的sql脚本。sql脚本的命名一定要规范,否则运行flyway会报错
一、简单介绍
Flyway 是一款开源的数据库版本管理工具。它可以很方便的在命令行中使用,或者在Java应用程序中引入,用于管理我们的数据库版本。
在项目或产品中,很难一开始就把业务理清楚,把数据库表设计好,因此数据表也会在迭代周期不断迭代。在Java应用程序中使用Flyway,能快速有效地用于迭代数据库表结构,并保证部署到测试环境或生产环境时,数据表都是保持一致的。
flyway官方文档https://flywaydb.org/documentation/
二、为什么要使用flyway
在多人开发的项目中,我们都习惯了使用SVN或者Git来对代码做版本控制,主要的目的就是为了解决多人开发代码冲突和版本回退的问题。
其实,数据库的变更也需要版本控制,在日常开发中,我们经常会遇到下面的问题:
- 自己写的SQL忘了在所有环境执行。
- 别人写的SQL我们不能确定是否都在所有环境执行过了。
- 有人修改了已经执行过的SQL,期望再次执行。
- 需要新增环境做数据迁移。
- 每次发版需要手动控制先发DB版本,再发布应用版本。
- 其它场景。
有了flyway,这些问题都能得到很好的解决。
三、flyway是如何工作的
flyway工作流程如下:
- 项目启动,应用程序完成数据库连接池的建立后,Flyway自动运行。
- 初次使用时,flyway会创建一个 flyway_schema_history 表,用于记录sql执行记录。
- Flyway会扫描项目指定路径下(默认是 classpath:db/migration )的所有sql脚本,与 flyway_schema_history 表脚本记录进行比对。如果数据库记录执行过的脚本记录,与项目中的sql脚本不一致,Flyway会报错并停止项目执行。
- 如果校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。
四、如何使用flyway
注:以下为本篇文章内容对应源码,可以自行下载测试,仅需要修改对应的数据库账号密码配置即可。如果对您有帮助,麻烦帮我点个赞或者star,你的鼓励,就是我更新的动力。
flyway使用示例代码https://github.com/wangming2674/flyway-use-demo
1、先要初始化一个SpringBoot项目,引入依赖
我使用的版本是2.3.5.RELEASE,引入mysql、mybatis、flyway等依赖,pom.xml文件内容如下:
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mysql.version>8.0.25</mysql.version>
<mybatis-starter.version>2.2.1</mybatis-starter.version>
<flyway.version>6.1.0</flyway.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>$mysql.version</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>$mybatis-starter.version</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>$flyway.version</version>
</dependency>
</dependencies>
2、在application.yml中添加相关配置
spring:
# 数据库连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/flyway-demo?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
flyway:
# 是否启用flyway
enabled: true
# 编码格式,默认UTF-8
encoding: UTF-8
# 迁移sql脚本文件存放路径,默认db/migration
locations: classpath:db/migration
# 迁移sql脚本文件名称的前缀,默认V
sql-migration-prefix: V
# 迁移sql脚本文件名称的分隔符,默认2个下划线__
sql-migration-separator: __
# 迁移sql脚本文件名称的后缀
sql-migration-suffixes: .sql
# 迁移时是否进行校验,默认true
validate-on-migrate: true
# 当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表
baseline-on-migrate: true
3、根据配置文件中填写的脚本存放路径,创建文件夹
根据上面配置文件中的脚本存放路径,我们需要在resource目录下建立文件夹 db/migration 。
4、添加需要运行的sql脚本。sql脚本的命名一定要规范,否则运行flyway会报错
命名规则主要有两种:
- 仅需要被执行一次的SQL命名以大写的"V"开头,V+版本号(版本号的数字间以”.“或”_“分隔开)+双下划线(用来分隔版本号和描述)+文件描述+后缀名。例如: V20201100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql 。
- 可重复运行的SQL,则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。(不推荐使用)比如: R__truncate_user_dml.sql 。
其中,V开头的SQL执行优先级要比R开头的SQL优先级高。
创建完成后,目录应如下所示:
其中2.1.6、2.1.7和every的文件夹不会影响flyway对SQL的识别和运行,可以自行取名和分类。
5、启动项目, 通过flyway执行定义好的脚本
在控制台可以看到相关日志打印,并在数据库中查看到已经创建好的表和相关记录变更。
6、提示说明
如果我们修改V2__add_user.sql
中的内容,再次执行的话,就会报错,提示信息如下:
[ERROR] Migration checksum mismatch for migration version 2
如果我们修改了R__add_unknown_user.sql
,再次执行的话,该脚本就会再次得到执行,并且flyway的历史记录表中也会增加本次执行的记录。
五、maven插件的使用
1、配置插件
以上步骤中,每次想要migration都需要运行整个springboot项目,并且只能执行migrate一种命令,其实flyway还是有很多其它命令的。maven插件给了我们不需要启动项目就能执行flyway各种命令的机会。
在pom.xml中引入flyway的插件,同时配置好对应的数据库连接。
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>5.2.4</version>
<configuration>
<url>jdbc:mysql://localhost:3306/flyway-demo?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
</url>
<user>root</user>
<password>root</password>
<driver>com.mysql.cj.jdbc.Driver</driver>
</configuration>
</plugin>
</plugins>
</build>
2、插件命令说明
此时,我们双击执行上图中的flyway:migrate的效果和启动整个工程执行migrate的效果是一样的。
其它命令的作用如下:
-
baseline
对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。
-
clean
清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。
-
info
用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。
-
repair
repair操作能够修复metaData表,该操作在metadata出现错误时很有用。
-
undo
撤销操作,社区版不支持。
-
validate
验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。
六、flyway知识补充
- flyway执行migrate必须在空白的数据库上进行,否则报错。
- 对于已经有数据的数据库,必须先baseline,然后才能migrate。
- clean操作是删除数据库的所有内容,包括baseline之前的内容。
- 尽量不要修改已经执行过的SQL,即便是R开头的可反复执行的SQL,它们会不利于数据迁移。
- 当需要做数据迁移的时候,更换一个新的空白数据库,执行下migrate命令,所有的数据库更改都可以一步到位地迁移过去。
七、flyway配置清单
flyway.baseline-description对执行迁移时基准版本的描述.
flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
flyway.check-location检查迁移脚本的位置是否存在,默认false.
flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false.
flyway.enabled是否开启flywary,默认true.
flyway.encoding设置迁移时的编码,默认UTF-8.
flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false.
flyway.init-sqls当初始化好连接时要执行的SQL.
flyway.locations迁移脚本的位置,默认db/migration.
flyway.out-of-order是否允许无序的迁移,默认false.
flyway.password目标数据库的密码.
flyway.placeholder-prefix设置每个placeholder的前缀,默认$.
flyway.placeholder-replacementplaceholders是否要被替换,默认true.
flyway.placeholder-suffix设置每个placeholder的后缀,默认.
flyway.placeholders.[placeholder name]设置placeholder的value
flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema.
flyway.sql-migration-prefix迁移文件的前缀,默认为V.
flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__
flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql
flyway.tableflyway使用的元数据表名,默认为schema_version
flyway.target迁移时使用的目标版本,默认为latest version
flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
flyway.user迁移数据库的用户名
flyway.validate-on-migrate迁移时是否校验,默认为true
FlyWay入门教程
文章目录
Flyway
Flyway by Redgate • 数据库迁移变得简单。 ---- 数据库的版本控制
1. 概述
Flyway 是一款开源的数据库版本管理工具。它可以很方便的在命令行中使用,或者在Java应用程序中引入,用于管理我们的数据库版本。
用通俗的话讲,Flyway可以像Git管理不同人的代码那样,管理不同人的sql脚本,从而做到数据库同步。
应用场景:
在项目或产品中,很难一开始就把业务理清楚,把数据库表设计好,因此数据表也会在迭代周期不断迭代。在Java应用程序中使用Flyway,能快速有效地用于迭代数据库表结构,并保证部署到测试环境或生产环境时,数据表都是保持一致的。
适用人员:
- 架构人员:搭建框架初始数据库的;
- 开发人员:在Flyway框架下做sql改动的;
支持的数据库包括:
2. 工作原理与基本概念
工作原理概述
当 Flyway 连接数据库中的 schema 后,会先检查是否已存在 flyway_schema_history 表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息。
flyway_schema_history 表结构:
当 flyway_schema_history 存在后,Flyway 会扫描文件系统或应用中的 classpath 目录的数据迁移文件,然后根据它们的版本号进行按序迁移,如下图:
由于 flyway_schema_history 表中记录了迁移的版本号,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行。(并非真正忽略,而是会校验checksum值是否一致,以此来保证历史版本文件未被篡改)
所以每次当你打算升级数据库时(包含DDL、DML语句),只需要在指定路径下创建一个版本号大于历史记录表中当前最大的版本号的迁移文件即可。在下次flyway启动时(随项目启动或其他形式),数据库将会自动完成升级,你无须再手动执行脚本。
基本概念
Migration(迁移)
使用 Flyway,对数据库的所有更改都称为迁移。迁移可以是版本化的或 可重复的。版本化迁移有两种形式:常规和撤消。
Migration的方式包括:
- SQL
- Java
- 脚本
迁移最常使用SQL编写。这使得上手和利用任何现有的脚本、工具和技能变得容易。它使您可以访问数据库的全部功能,并且无需了解任何中间翻译层。
基于 SQL 的迁移通常用于
- DDL 更改(TABLES、VIEWS、TRIGGERS、SEQUENCES……的 CREATE/ALTER/DROP 语句)
- 简单的参考数据更改(参考数据表中的 CRUD)
- 简单的批量数据更改(常规数据表中的 CRUD)
**命名:**为了被 Flyway 采用,SQL migrations 必须符合以下命名模式:
3. 安装和基本使用
命令行
Flyway 命令行工具是一个独立的 Flyway 发行版。它在 Windows、macOS 和 Linux 上运行,主要适用于希望从命令行迁移数据库而无需将 Flyway 集成到其应用程序中也无需安装构建工具的用户。 Flyway命令行工具下载地址
注意:Flyway社区版删除了Mysql5.7的支持!!!!社区版不支持undo等命令
安装
目录结构
配置环境变量
# Win+R 输入:
rundll32.exe sysdm.cpl,EditEnvironmentVariables
添加目录到环境变量:
添加到path中:
使用命令行测试环境变量:
使用
示例前置条件: 一个名为 flyway的MySQL数据库。
-
配置数据库连接信息
在
conf/flyway.conf
中配置如下信息: -
配置sql文件路径
flyway.locations=filesystem:\\\\D:\\Flyway\\flyway-commandline-9.1.5-windows-x64\\flyway-9.1.5\\sql
-
添加sql脚本
-
执行命令
flyway migrate
-
查看数据库中的表信息
-
再次执行
flyway migrate
因为当前sql文件与之前没有变化,所以不会执行任何sql。
命令
-
migrate
# 将架构迁移到最新版本。如果Flyway不存在,它将自动创建架构历史记录表。 flyway migrate
-
clean
# Clean 对开发和测试有很大帮助。通过彻底清除已配置的模式,它将有效地为您提供新的开始。所有对象(表、视图、过程……)都将被删除。注意:谨慎使用,配置中默认禁用 flyway clean
-
info
# 打印有关所有迁移的详细信息和状态信息。 flyway info
-
validate
# 根据可用的migration验证应用的迁移。验证可帮助您验证应用于数据库的迁移是否与本地可用的迁移相匹配。 flyway validate
-
undo
# 撤消最近应用的版本化迁移。(社区版不支持) flyway undo
-
baseline
# Baseline 用于通过在特定版本上对现有数据库进行基线来将 Flyway 引入现有数据库。这将导致Migrate忽略直到并包括基线版本的所有迁移。然后将照常应用较新的迁移。 flyway baseline
-
repair
# 修复Flyway模式历史记录表。这将执行以下操作: - 删除失败的迁移条目(仅适用于不支持 DDL 事务的数据库) - 将应用迁移的校验和、描述和类型与可用迁移重新对齐 - 将所有丢失的迁移标记为已删除 flyway repair
Java API
-
引入依赖
<!-- flyway --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>5.2.4</version> </dependency>
-
配置迁移文件
在项目的 src/main/resources 下创建 db/migration 目录,该目录下放置需要数据迁移的文件。
-
编写Java程序
import org.flywaydb.core.Flyway; /** * @ClassName: FlywayTest * @Description: Flyway * @Author: Ze WANG * @Date: 2022/8/18 **/ public class FlywayTest public static void main(String[] args) String url = "jdbc:mysql://ip:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8"; String user = "root"; String password = "123456"; Flyway flyway = Flyway.configure().dataSource(url, user, password).load(); flyway.migrate();
初始化数据库,运行程序观察:
Spring Boot
前提条件,一个SpringBoot 程序
-
引入依赖
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
-
配置application
flyway: enabled: true # 默认clean为false,这里为了测试,谨慎使用 clean-disabled: true # 如果数据库不是空表需要配置为true baseline-on-migrate: true baseline-version: 0 locations: - classpath:db/migration/
-
启动项目
# 启动项目后数据库会根据脚本变更
以上是关于flyway的快速入门教程的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Spring Boot 中将 Flyway 迁移与 postgresQL 连接起来
将 Flyway 设置为在 Spring Boot 中使用不同的环境