Spring Boot 使用 flyway

本贴最后更新于 2031 天前,其中的信息可能已经时过境迁

概念性问题参考 官方文档

概述

Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。

它基于 7 个基本命令: Migrate, Clean, Info, Validate, Undo, Baseline and Repair.

Migrations 支持纯 sql 语句 或 java 代码。

它有一个命令行客户端。如果您在 JVM 上,我们建议使用 Java API(也适用于 Android)在应用程序启动时迁移数据库。或者,您也可以使用 Maven 插件或 Gradle 插件。

如果这还不够,可以使用 Spring Boot,Dropwizard,Grails,Play,SBT,Ant,Griffon,Grunt,Ninja 等插件!

支持的数据库是 Oracle,SQL Server(包括 Amazon RDS 和 Azure SQL 数据库,DB2,MySQL(包括 Amazon RDS,Azure 数据库和 Google Cloud SQL),Aurora MySQL,MariaDB,Percona XtraDB 集群,PostgreSQL(包括 Amazon RDS,Azure 数据库,Google Cloud SQL 和 Heroku),Aurora PostgreSQL,Redshift,CockroachDB,SAP HANA,Sybase ASE,Informix,H2,HSQLDB,Derby 和 SQLite。迁移

通过官方文档对 flyway 有了个初步认识,因为主要使用其 Migrations 功能 ,所以着重看一下这部分。

Migrate (迁移)

官方对其的描述是 Migrates the schema to the latest version. 将架构迁移到最新版本。

看描述就是执行程序中的 SQL 脚本文件并更新(如果不存在会先创建)flyway_schema_history 表。

null

其中执行 SQL 脚本就相当于是在更新数据库版本,执行过的脚本文件信息会在 flyway_schema_history 表中生成一条记录。

迁移最好在应用程序启动时执行,以避免数据库和代码期望之间的任何不兼容型。即代码中用到的数据结构是要 migrate 过的新的数据结构,如果 migrate 设定在程序执行中的某个节点再执行,可能就会造成部分代码与数据库不兼容问题。

执行规则:

  1. 执行是按版本号顺序进行的,比如当前数据库版本是 5,程序中新增了版本号为 6、7、8、9 的脚本文件,那么下次程序运行时会顺序执行 6、7、8、9 脚本。

  2. 执行过的脚本文件不会再被执行。

    (注:只有以 V 开头的版本控制型脚本是这样)

Migration(迁移)

使用 Flyway 对数据库的所有更改都称为迁移。迁移可以是**versioned (版本化)的,也可以是repeatable(可重复)的。版本化迁移有两种形式:常规撤销**。

脚本文件命名规则决定了脚本的 migration 类型

为了能够被 flyway 识别,迁移脚本必须符合以下命名规则:

flywayNaming.png

文件名由以下部分组成:

  • Prefix(前缀):V 开头的代表版本化迁移, U 开头代表 撤销迁移, R 开头代表可重复迁移 (前缀可通过配置文件设置为别的字符)

  • Version(版本):版本迁移时的版本号,必要且不能重复,通常为递增整数,若有需要,也可以使用 . 表示小版本更新,比如下列版本号都是符合要求的

    • 1

    • 001

    • 5.2

    • 1.2.3.4.5.6.7.8.9

    • 205.68

    • 20130115113556

    • 2013.1.15.11.35.56

    • 2013.01.15.11.35.56

    撤销迁移的

  • Separator(分隔符): __ 双下划线 (可通过配置文件设置为别的字符)

  • Description(描述): 用于描述脚本文件执行的内容,单词使用单下划线或空格分隔

  • Suffix(后缀): 因为此处使用的 SQL 脚本执行的更新,所以后缀使用 .sql ,如果是基于 Java 的迁移,因为创建的是 java 文件,也就不需要后缀。(可通过配置文件设置为别的字符)

在 spring-boot 项目中使用 flyway

项目中使用原来的 mysql 数据库,所以只在 Maven 中引入 flyway 即可。

<dependency>  
 <groupId>org.flywaydb</groupId>  
 <artifactId>flyway-core</artifactId>  
 <version>5.2.4</version>  
</dependency>

Gradle 参考官方文档 Gradle

各种版本的资源可在 mvnrepository 找到。

在 application.properties 文件中配置一些基本属性。

# 是否开启flyway,默认是 true,如果打算一直用flyway可以不用配置。当某次执行代码时不想用flyway 时可以把此项设为false;  
spring.flyway.enabled=true  
# 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.  
spring.flyway.baseline-on-migrate=true  
#  配合 baseline-on-migrate 使用,因为创建 flyway_schema_history 表时也会占用一条记录,如果不加初始版本=0,那么V1里的sql就不会执行
# (这个问题我一开始还以为它就是这么设计的,第一个版本我以为就是被占用的,直到我发现别人的是可以执行的。。。。)
spring.flyway.baseline-version=0
# 迁移脚本的位置,默认db/migration.  
spring.flyway.locations=classpath:/db/migration

第一次执行时 baseline-on-migrate 一定要设为 true,否则会报异常

SpringBoot 配置属性之 Migration

配置完后 就在配置的 locations 的位置创建 对应的文件夹,然后写好脚本文件启动程序就行了。

1558603275921.png
1558603377682.png
1558604317925.png

为了测试上文提到的版本执行规则,我先删除了 flyway_schema_history 表,重新执行的时候就依次执行了几个 V 开头的 sql 脚本。

根据 flyway_schema_history 表中的记录显示,最后还执行了 R 开头的可重复脚本。注意:虽然 R 是 可重复执行的,但只有文本发生改变时才会重复执行,如果这个脚本没有修改过,它就不会重复执行。注意:R 文件执行时并不是只执行追加的部分,它依然是全文执行。

还有一点就是 U 开头的那个撤销迁移 脚本 没有执行。查了一下官方文档,说是只有 专业版企业版才支持 undo 这个功能,不知道这里没有执行是不是这个原因。而且官方文档也提到这个功能并不如设想那样好用,所以这里也就不再深究了。

对于执行的 SQL 脚本,Flyway 不仅支持常规的 SQL 语法,还支持使用可配置的前缀和后缀替换占位符。

示例:

/* Single line comment */  
CREATE TABLE test_user (  
 name VARCHAR(25) NOT NULL,  
 PRIMARY KEY(name)  
);  
​  
/*  
Multi-line  
comment  
*/  
​  
-- Placeholder  
INSERT INTO ${tableName} (name) VALUES ('Mr. T');

以上是基于 SQL 的迁移。

下面看一下基于 Java 的迁移。

命名规则与 SQL 文件基本一致,只是这里由于要创建的是 Java 文件,所以命名时不能使用 "." 号进行小版本控制。可以使用 "_" 单下划线。如

V1__add_new_table

V1_1__alter_table 这样的命名。

脚本文件支持 使用 JDBC。

1558669370849.png

下面看一下 flyway_schema_history 表的字段

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注
  • flyway
    1 引用
  • migration
    1 引用
1 操作
mnizht 在 2019-05-31 17:21:39 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...