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. Spring Boot 2.x基础教程:使用Flyway管理数据库版本

    之前已经介绍了很多在Spring Boot中使用MySQL的案例,包含了Spring Boot最原始的 JdbcTemplate(https://blog.didispace.com/spring-b ...

  2. flyway常用配置_Spring Boot 2.x基础教程:使用Flyway管理数据库版本

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

  3. Maven学习总结(33)——开发人员如何使用 Flyway 插件管理数据库版本

    一.前言. 想到要管理数据库的版本,是在实际产品中遇到问题后想到的一种解决方案,当时各个环境的数据库乱作一团,没有任何一个人(开发.测试.维护人员)能够讲清楚当前环境下的数据库是哪个版本,与哪个版本的 ...

  4. flyway版本号_Flyway 管理数据库版本变更

    logo 一. Flyway介绍 Flyway的定位:数据库的版本控制. Flyway是一款开源的数据库版本管理工具,Flyway可以独立于应用实现管理并跟踪数据库的变更(DDL和DML语句),Fly ...

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

    久违了的Spring Boot系列,今天抽空更新一篇.之前写过很多篇关于数据访问的文章了,比如下面这些: 使用JdbcTemplate 使用Spring-data-jpa简化数据访问层(推荐) 多数据 ...

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

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

  7. 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解...

    本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...

  8. 为热门项目 若依(ruoyi) 添加flyway,自动管理数据库版本

    flyway大家应该都听说过甚至用过,是一种数据库管理工具.多个人协作开发,或者是项目部署的时候,非常方便,不需要再mysql里面去初始化表结构和数据,项目启动时,根据flyway_schema_hi ...

  9. flyway版本号_使用flyway作为数据库版本工具

    1. 在maven中添加jar包. org.flywaydb flyway-core 5.2.4 2.在classpath目录中添加文件夹 db.migration --文件名称是可以改变 3.在配置 ...

最新文章

  1. 11g RMAN Restore archivelog用法
  2. python打包成exe 可执行文件 。教程
  3. 5.单行函数,多行函数,字符函数,数字函数,日期函数,数据类型转换,数字和字符串转换,通用函数(case和decode)
  4. java中通过JNA调用dll
  5. Spring5的AOP 和设备支持
  6. P2216 [HAOI2007]理想的正方形
  7. 详解ROS中的TF使用
  8. 《设计模式详解》行为型模式 - 解释器模式
  9. debian下,下载linux内核
  10. 内存不能为read故障分析
  11. 水仙花数c语言程序vb,VB编程:求水仙花数
  12. html全部颜色代码大全,html代码大全(基础使用代码)(颜色代码完整版)
  13. 冒泡排序及其优化(三种优化)
  14. uniapp Apple iOS 绑定解绑
  15. scikit-image HOG feature 提取函数使用心得。
  16. 多线程之基于积分法与欧拉恒等式法的圆周率计算及OMP优化
  17. 什么是短视频电商,短视频电商的商业模式标题】
  18. WeaQA:Weak Supervision via Captions for Visual Question Answering 论文笔记
  19. 几何光学学习笔记(12)- 4.1平面镜成像
  20. Apache访问控制和Web虚拟主机

热门文章

  1. “中国智造”为System x提供创新源动力
  2. java和js获取当前天之后或之前7天(任意)日期
  3. git与sourceTree
  4. more effective C++
  5. WCF服务编程 学习笔记(2)
  6. Android简单实现将手机图片上传到服务器中
  7. SqlMap常用参数(一)
  8. Flask的session使用
  9. URAL 1033 Labyrinth
  10. Cheatsheet: 2011 12.01 ~ 12.12