Spring Boot集成Flyway实现数据库版本控制?_第1张图片

今天给大家介绍一款比较好用的数据库版本控制工具Flyway。在通过Spring Boot构建微服务的过程中,一般情况下在拆分微服务的同时,也会按照系统功能的边界对其依存的数据库进行拆分。在这种情况下,微服务的数据库版本管理对于研发工程管理来说,就会是一个比较棘手的问题。

在正常的代码管理流程中,从产品研发研发的过程看,一般会经历功能开发、研发测试、集成测试、预发布测试、上线等多个环节。而对于同一个产品功能,可能还会涉及对多个微服务代码及数据库结构的改动。

而这些改动需要我们在以上流程中每发布一个环境,都需要提前预置好数据库结构变更的依赖。假设,我们开发完成需要发布到测试环境,那么就需要我们提前将改动的脚本在测试环境执行,测试环境完成测试后需要发布到预发布环境测试,也需要提前在预发布环境执行脚本。以往,这种过程都依赖于人工执行,如果想要保持所有环境数据库版本的一致性,很大程度上是需要依赖于人,环境比较少还好,但如果环境比较多的话,久而久之很容易就出现大家不维护的状态了。只有某天在某个环境进行测试时出错了,才会猛然发现有些服务的数据库变更脚本并没有得到执行,从而去补缺。

那么有没有一种比较智能的方式,在微服务启动的时候,就可以检测到数据库版本的变化,从而能够自动去执行变更的数据库脚本,以此来保证除生产外的大部分环境的数据库版本都可以自动一致呢?

答案是有多,市面上的方案也有一些,今天给大家介绍的是使用得比较广泛一点的Flyway。

Flyway概述

Flyway是一款数据库版本控制管理工具,功能上类似Git对代码的版本控制。Flyway支持市面上几乎所有的常用数据库,如Mysql、Oracle、PostgreSQL等。通过Flyway的管理,我们可以很轻松的跨多个环境管理数据库的schema及相关业务数据变更信息。例如,开发一个新功能创建一个新表,只需要将脚本按照规范的命名格式放置在项目的指定目录,那么应用就可以通过Flyway自动检测当前环境的数据库版本,从而自动帮我们完成相应环境的结构同步,而不再需要像之前那样手动执行。

除了数据库schema结构的变更外,数据的变更也可以通过这种方式同步,例如我们在字典表新增了一条字典数据,类似地也可以通过这种方式去管理同步数据变更记录。

Spring Boot集成Flyway

在Spring Boot项目中使用Flyway是非常方便和简单的。首先我们需要引入Flyway的依赖及插件依赖,如下:



    org.flywaydb
    flyway-core
    5.0.3
 
 
     org.flywaydb
     flyway-maven-plugin
     5.0.3
 

至此,我们就完成了Spring Boot项目对Flyway的集成,是不是很简单呢!完成Flyway的集成后,我们的数据库脚本需要怎么管理才能被Flyway自动识别并得到正确执行呢?

我们需要在项目在resources中建立db/migration文件夹,并通过V1.0__init.sql(是__而不是_)类似这样的命名方式来命名我们每次需要变更的数据库脚本。例如我们创建了一个全新的项目,那么我们就可以把这个项目的初始化数据库脚本放到这里,如:V1.0__init_database.sql。

这样,如果你此时连接一个全新的数据库,启动Spring Boot项目Flyway就会自动去扫描db/migration目录下未被执行的脚本,从而帮你完成数据库脚本的同步。随着功能的开发,假设有一个新的数据库变更需要执行,那么我们就需要再建立一个新的脚本文件,如:V1.1__add_dictdata.sql这样,下次启动项目的时候,这个脚本也就会自动执行了。关于数据脚本的命名规范除了V1.1这样的版本号之外,后面的部分大家可以根据变更的类型起一个有意义、相对规范的名字即可。

说到这里,是不是有点疑惑,Flyway到底是怎么做才能做到对数据库版本的管理的呢?事实上,如果我们首次集成Flyway,启动项目后Flyway会在对应的数据库中创建一张名为"flyway_schema_history"的表,这种表就会记录所有脚本版本的执行情况,如:

Spring Boot集成Flyway实现数据库版本控制?

也就是说,实际上Flyway对数据库脚本版本的控制完全是依赖于维护了这样一张信息表。假设有个脚本已经被成功执行过,如果我们人为的删除这种表中的执行记录,会怎么样呢?答案是,Flyway会再次执行,并且因为执行过,如果脚本中有重建表的SQL,那么很可能会造成数据丢失的情况,所以使用Flyway对于这种表的维护是至关重要的,切记切记!

另外,大多数情况下,我们在使用Flyway之前,可能数据库已经执行过了一些脚本,如果此时要重新将其管理起来,并且想达到之前执行过的脚本不再自动执行的效果的话,此时可能就需要我们手工在flyway_schema_history表中插入对应的脚本执行版本记录,从而临时绕开下Flyway了。

后记

Flyway是一个比较自动化的数据库版本控制工具,用好了会方便我们开发提高研发效率,另一方面,再好的工具也在于人怎么使用,如果没有一套完整的操作规范,太自动的工具也可能会带来灾难,如重要的数据被重建导致丢失的情况!所以,大部分情况下Flyway对于测试及开发环境数据库版本的维护还是很方便的,至于生产嘛,还是建议通过一套流程约定,人工执行管理比较保险!