一.什么是Flyway?

    Flayway是一款数据库版本控制管理工具,支持数据库版本自动升级,Migrations可以写成sql脚本,也可以写在java代码里;不仅支持Command Line和java api ,也支持Build构建工具和Spring boot,也可以在分布式环境下能够安全可靠安全地升级数据库,同时也支持失败恢复。

    Flyway最核心的就是用于记录所有版本演化和状态的MetaData表,Flyway首次启动会创建默认名为SCHEMA_VERSION的元素局表。 表中保存了版本,描述,要执行的sql脚本等;

   为什么使用Flyway?

      通常在项目开始时会针对数据库进行全局设计,但在开发产品新特性过程中,难免会遇到需要更新数据库Schema的情况,比如:添加新表,添加新字段和约束等,这种情况在实际项目中也经常发生。

    那么,当开发人员完成了对数据库更的SQL脚本后,如何快速地在其他开发者机器上同步?并且如何在测试服务器上快速同步?以及如何保证集成测试能够顺利执行并通过呢?

      假设以Spring Boot技术栈项目为例,可能有人会说,本地使用Hibernate自动更新数据库Schema模式,然后让QA或DEV到测试服务器上手动执行SQL脚本,同时可以写一个Gradle任务自动执行更新。

    个人觉得,对于Hibernate自动更新数据库,感觉不靠谱,不透明,控制自由度不高,而且有时很容易就会犯错,比如:用SQL创建的某个字段为VARCHAR类型,而在Entity中配置的为CHAR类型,那么在运行集成测试时,

    自动创建的数据库表中的字段为CHAR类型,而实际SQL脚本期望的是VARCHAR类型,虽然测试通过了,但不是期望的行为,并且在本地bootRun或服务器上运行Service时都会失败。

    另外,到各测试服务器上手动执行SQL脚本费时费神费力的,干嘛不自动化呢,当然,对于高级别和PROD环境,还是需要DBA手动执行的。最后,写一段自动化程序来自动执行更新,想法是很好的,

    那如果已经有了一些插件或库可以帮助你更好地实现这样的功能,为何不好好利用一下呢,当然,如果是为了学习目的,重复造轮子是无可厚非的。

    其实,以上问题可以通过Flyway工具来解决,Flyway可以实现自动化的数据库版本管理,并且能够记录数据库版本更新记录

二,怎么使用Flyway(这里使用Springboot整合Flyway)

  1.引入Maven依赖 和 插件(可选,插件是作用是:不需要启动项目就能执行Flyway各种命令)

<dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>5.0.3</version>
</dependency>
<plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>5.0.3</version>
</plugin>

  

Java不同数据库间数据迁移_SQL

  此时,我们双击执行上图中的flyway:migrate的效果和启动整个工程执行migrate的效果是一样的。

  其它命令的作用如下列出,各位可自行实验体会:

  1.   baseline
    对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。
  2.   clean
    清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。
  3.   info
    用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。
  4.   repair
    repair操作能够修复metaData表,该操作在metadata出现错误时很有用。
  5.   undo
    撤销操作,社区版不支持。
  6.   validate
    验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

  2.编辑Flyway相关的配置文件

server.port=8088
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

  3.在classpath下新建/db/migration文件夹,用于存放SQL脚本

  4.创建我们所需要的并且需要同步数据库的SQL脚本

  注意文件的命名规则:

  这里有两类文件:

    1.仅需要被执行一次的SQL命名以大写的V开头,后面跟上0-9数字的组合,数字之间可以用"."或者下划线"_"分割开,然后在以两个下划线分割,其后跟文件名称,最后以.sql结尾,

     如,V2.1.5__create_user_ddl.sqlV4.1_2__add_user_dml.sql

    2.可重复运行的SQL,则以则以大写的“R”开头,后面再以两个下划线分割,其后跟文件名称,最后以.sql结尾。

    比如,R__truncate_user_dml.sql

    其中,V开头的SQL执行优先级要比R开头的SQL优先级高。

use testdb;
 
CREATE TABLE person (
  id int(11) NOT NULL AUTO_INCREMENT,
  first varchar(100) NOT NULL,
  last varchar(100) NOT NULL,
  dateofbirth DATE DEFAULT null,
  placeofbirth varchar(100) not null,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
insert into person (first,last,dateofbirth,placeofbirth) values('Dursun','KOC', STR_TO_DATE('02/10/1982', '%m/%d/%Y'),'Erzincan');
 
insert into person (first,last,dateofbirth,placeofbirth) values('Durseeun','KeeOC', STR_TO_DATE('05/10/1982', '%m/%d/%Y'),'Erzeeincan');

 

三.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

 

参考文章:

  https://www.jianshu.com/p/567a8a161641