Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star 数量看, flyway 更受欢迎.

============================== 
flyway 命令行工具和 maven 插件
==============================
对于 SpringBoot 项目开发, 其实不需要专门安装 flyway 命令行工具和 maven 插件, SpringBoot 启动就会自动执行 DB migrate 操作. 对于其他的 flyway 操作, 就需要使用命令行工具或 maven 插件了.

flyway 提供命令行工具, 常用的命令包括:
Clean: 删除所有创建的数据库对象, 包括用户、表、视图等. 注意不要在生产库上执行 clean 操作. 
Migrate: 对数据库依次应用版本更改. 
Info: 获取目前数据库的状态. 那些迁移已经完成, 那些迁移待完成. 所有迁移的执行时间以及结果. 
Validate: 验证已 Apply 的脚本是否有变更, Flyway 的 Migration 默认先做 Validate. 
Baseline: 根据现有的数据库结构生成一个基准迁移脚本. 
Repair: 修复命令尽量不要使用, 修复场景有: 1. 移除失败的 migration 记录. 2.已经应用的 SQL 脚本被修改, 我们想重新应用该 SQL 脚本.

maven 插件, 最新 maven 插件见 https://mvnrepository.com/artifact/org.flywaydb/flyway-maven-plugin

<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.0.3</version>
</plugin>

maven插件命令, mvn flyway:migrate

==============================
Flyway 的工作原理
==============================
flyway 需要在 DB 中先创建一个 metdata 表 (缺省表名为 flyway_schema_history), 在该表中保存着每次 migration 的记录, 记录包含 migration 脚本的版本号和 SQL 脚本的 checksum 值. 当一个新的 SQL 脚本被扫描到后, Flyway 解析该 SQL 脚本的版本号, 并和 metadata 表已 apply 的的 migration 对比, 如果该 SQL 脚本版本更新的话, 将在指定的 DB 上执行该 SQL 文件, 否则跳过该 SQL 文件.

两个 flyway 版本号的比较, 采用左对齐原则, 缺位用 0 代替. 举例如下: 
1.2.9.4 比 1.2.9 版本高. 
1.2.10 比 1.2.9.4 版本高. 
1.2.10 和 1.2.010 版本号一样高, 每个版本号部分的前导 0 会被忽略.

Flyway SQL 文件可以分为两类: Versioned 和 Repeatable. 
Versioned migration 用于版本升级, 每个版本有唯一的版本号并只能 apply 一次. 
Repeatable migration 是指可重复加载的 migration, 一旦 SQL 脚本的 checksum 有变动, flyway 就会重新应用该脚本. 它并不用于版本更新, 这类的 migration 总是在 versioned migration 执行之后才被执行.

默认情况下, Migration SQL的命名规则如下图:

其中的文件名由以下部分组成,除了使用默认配置外,某些部分还可自定义规则.

prefix: 可配置,前缀标识,默认值 V 表示 Versioned, R 表示 Repeatable
version: 标识版本号, 由一个或多个数字构成, 数字之间的分隔符可用点.或下划线_
separator: 可配置, 用于分隔版本标识与描述信息, 默认为两个下划线__
description: 描述信息, 文字之间可以用下划线或空格分隔
suffix: 可配置, 后续标识, 默认为.sql

flyway 的 metadata 表结果如下:

CREATE TABLE  flyway_schema_history
(
installed_rank INT NOT NULL,
version VARCHAR(50),
description VARCHAR(200) NOT NULL,
type VARCHAR(20) NOT NULL,
script VARCHAR(1000) NOT NULL,
checksum INT,
installed_by VARCHAR(100) NOT NULL,
installed_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
execution_time INT NOT NULL,
success TINYINT(1) NOT NULL,
PRIMARY KEY (installed_rank),
INDEX flyway_schema_history_s_idx (success)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

==============================
pom.xml
==============================
spring-boot-starter-parent 包没有使用最新的 2.0.5, 最新版总是导致 HikariPool 无法初始化, 所以选择的版本是 2.0.4

    <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

flyway 其实仅依赖 spring-boot-starter-jdbc 包,

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

加上 spring-boot-maven-plugin , 可生成 fat jar.

    <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

==============================
application.properties 参数
==============================

## 设定 db source 属性
spring.datasource.url=jdbc:mysql://localhost:3306/world
spring.datasource.username=root
spring.datasource.password=toor ## 设定 flyway 属性
spring.flyway.cleanDisabled = true
# flyway 的 clean 命令会删除指定 schema 下的所有 table, 杀伤力太大了, 应该禁掉.
spring.flyway.enabled = true
# 启用或禁用 flyway
spring.flyway.locations =classpath:db/migration
# 设定 SQL 脚本的目录,多个路径使用逗号分隔, 比如取值为 classpath:db/migration,filesystem:/sql-migrations
spring.flyway.baselineOnMigrate=true
# 如果指定 schema 包含了其他表,但没有 flyway schema history 表的话, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令.
# 设置 spring.flyway.baseline-on-migrate 为 true 后, flyway 将在需要 baseline 的时候, 自动执行一次 baseline.
spring.flyway.baselineVersion=1
# 指定 baseline 的版本号,缺省值为 1, 低于该版本号的 SQL 文件, migrate 的时候被忽略.
#spring.flyway.encoding=
# Encoding of SQL migrations (default: UTF-8)
spring.flyway.table=flyway_schema_history_myapp
# 设定 flyway 的 metadata 表名, 缺省为 flyway_schema_history
spring.flyway.outOfOrder=true
# 开发环境最好开启 outOfOrder, 生产环境关闭 outOfOrder .
#spring.flyway.schemas=
# 需要 flyway 管控的 schema list, 缺省的话, 使用的时 dbsource.connection直连上的那个 schema, 可以指定多个schema, 但仅会在第一个schema下建立 metadata 表, 也仅在第一个schema应用migration sql 脚本. 但flyway Clean 命令会依次在这些schema下都执行一遍.

更多参数见 https://flywaydb.org/documentation/configfiles , 需要说明的是, 这些参数配到springboot2 项目中, 需要加上 spring. 前缀.

==============================
flyway 最佳实践
============================== 
1. SQL 的文件名
开发环境和生产环境的 migration SQL 不共用. 开发过程往往是多人协作开发, DB migration 也相对比较频繁, 所以 SQL 脚本会很多. 而生产环境 DB migration 往往由 DBA 完成, 每次升级通常需要提交一个 SQL 脚本.

(1). 开发环境 SQL 文件建议采用时间戳作为版本号. 
开发环境 SQL 文件建议采用时间戳作为版本号, 多人一起开发不会导致版本号争用, 同时再加上生产环境的版本号, 这样的话, 将来手工 merge 成生产环境 V1.2d migration 脚本也比较方便, SQL 文件示例:
V20180317.10.59__V1.2_Unique_User_Names.sql
V20180317.14.59__V1.2_Add_SomeTables.sql

(2). 生产环境 SQL 文件, 应该是手动 merge 开发环境的 SQL 脚本, 版本号按照正常的版本, 比如 V2.1.5_001__Unique_User_Names.sql

2. migration 后的SQL 脚本不应该再被修改.

3. spring.flyway.outOfOrder 取值 true /false
对于开发环境, 可能是多人协作开发, 很可能先 apply 了自己本地的最新 SQL 代码, 然后发现其他同事早先时候提交的 SQL 代码还没有 apply, 所以 开发环境应该设置 spring.flyway.outOfOrder=true, 这样 flyway 将能加载漏掉的老版本 SQL 文件; 而生产环境应该设置 spring.flyway.outOfOrder=false

4. 多个系统公用要 DB schema 
很多时候多个系统公用一个 DB schema , 这时候使用 spring.flyway.table 为不同的系统设置不同的 metadata 表, 缺省为 flyway_schema_history

==============================
参考
==============================
https://blog.waterstrong.me/flyway-in-practice/
http://www.huangbowen.net/blog/2015/04/08/introduction-of-flyway/
http://dbabullet.com/index.php/2018/03/29/best-practices-using-flyway-for-database-migrations/
https://woodylic.github.io/2017/03/23/manage-database-migration-using-maven-and-flyway/
http://blog.didispace.com/spring-boot-flyway-db-version/
http://coyee.com/article/12092-database-versioning-with-flyway-and-java

转:SpringBoot系列: 使用 flyway 管理数据库版本的更多相关文章

  1. SpringBoot系列: 使用 flyway 管理数据库版本

      Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star ...

  2. Spring Boot 2.x基础教程:使用Flyway管理数据库版本

    之前已经介绍了很多在Spring Boot中使用MySQL的案例,包含了Spring Boot最原始的JdbcTemplate.Spring Data JPA以及我们国内最常用的MyBatis.同时, ...

  3. flyway 管理数据库版本

    Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star 数 ...

  4. 使用 Liquibase 管理数据库版本 - SpringBoot 2.7 .2 实战基础

    优雅哥 SpringBoot 2.7 .2 实战基础 - 05 -使用 Liquibase 管理数据库版本 在企业开发中,数据库版本管理好像是一个伪命题,大多项目都是通过 Power Designer ...

  5. 使用Flyway来管理数据库版本

    使用Flyway来管理数据库版本 Flyway是什么 Flyway是一款数据库迁移(migration)工具. 它可以帮助我们在不同环境保持数据库的同步,减少手工操作,避免数据导入的顺序错误,同时也减 ...

  6. Spring Boot教程(四十)使用Flyway来管理数据库版本

    在上面的使用JdbcTemplate一文中,主要通过spring提供的JdbcTemplate实现对用户表的增删改查操作.在实现这个例子的时候,我们事先在MySQL中创建了用户表.创建表的过程我们在实 ...

  7. SpringBoot整合Flyway(数据库版本迁移工具)

    简介 在团队开发当中,有可能每个人都是使用自己本地的数据库.当数据库的表或者字段更新时,往往需要告知团队的其他同事进行更新. Flyway数据库版本迁移工具,目的就是解决该问题而诞生的(我自己想的). ...

  8. Spring Boot中使用Flyway来管理数据库版本

    flyway是一个开源的数据库迁移工具.类似于数据库的版本控制工具.flyway的数据库修改文件默认放在resource下的db.migration文件夹中,以V{version_number}__{ ...

  9. Flyway:Spring Boot中使用Flyway来管理数据库版本

    Flyway简介 Flyway是一个简单开源数据库版本控制器(约定大于配置),主要提供migrate.clean.info.validate.baseline.repair等命令.它支持SQL(PL/ ...

随机推荐

  1. kettle数据同步的5中方案

    数据同步:当数据源发生改变时,其他相关数据也跟着发展变化.根据需求不同可采取以下方案.1.触发器:在数据库建立增删改的触发器.触发器将变更放到一张临时表里.oracle同步cdc优点:实时同步缺点:影 ...

  2. Java中打印日志,这4点很重要!

    目录 一.预先判断日志级别 二.避免无效日志打印 三.区别对待错误日志 四.保证记录完整内容 打印日志,要注意下面4点. 一.预先判断日志级别 对DEBUG.INFO级别的日志,必须使用条件输出或者使 ...

  3. 在vue中如何使用axios

    1.前言 在Vue1.0的时候有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource. 关于为什么放弃推荐? -& ...

  4. Java性能分析神器--VisualVM Launcher[1]

    Java性能分析神器1--VisualVM Launcher VisualVM 当你日复一日敲代码的时候,当你把各种各样的框架集成到一起的时候,看着大功告成成功运行的日志,有没有那么一丝丝迷茫和惆怅: ...

  5. 文件输入输出函数fgetc/fputc及fgets/fputs等文件指针位置的变化

    文件打开后才可以对文件进行操作.也就是说,文件必须经历打开-操作-关闭的过程.如前所述,C语言对文件的操作都是通过调用标准I/O库函数来实现的.文件操作实际是指对文件的读写.文件的读操作就是从文件中读 ...

  6. Sturts2整合Spring报错:org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml];

    十一月 17, 2019 1:11:44 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRul ...

  7. 在 ASP.NET Core 项目中使用 MediatR 实现中介者模式

    一.前言  最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前 ...

  8. JAVA继承中子父类的构造方法

    首先,构造方法本身会有一个隐式的无参构造(默认): ①不写构造方法,类中的第一行代码事实上有一个默认的无参构造(系统会隐式为你写好) public class Student { private St ...

  9. 使用sklearn和caffe进行逻辑回归 | Brewing Logistic Regression then Going Deeper

    原文首发于个人博客https://kezunlin.me/post/c50b0018/,欢迎阅读! Brewing Logistic Regression then Going Deeper. Bre ...

  10. MyBatis 数值类型 where 条件配置的坑

    复现异常 我们先通过案例复现该类异常,测试项目地址:https://gitee.com/yin_jw/demo/tree/master/mybatis-demo/springboot-mybatis- ...