当前位置: 首页 > 科技观察

SpringBoot2实战:使用Flyway管理你的数据库版本变更_0

时间:2023-03-12 17:59:31 科技观察

1.前言随着项目的不断迭代,数据库的表结构和数据都在发生变化。有些业务甚至在多个环境版本中并行运行。在数据为王的时代,管理数据库的版本成为了迫切的需求。像Git这样的版本控制工具如何管理数据库?Flyway和Liquibase在Java项目中常用来管理数据库版本。其中,Flyway比较受欢迎。2.Flyway的特点Flyway之所以受欢迎,是因为它有以下优点:简单非常容易安装和学习,迁移方式也很容易被开发者接受。DedicatedFlyway专注于数据库迁移和版本控制,没有其他副作用。强大专为持续交付而设计。让Flyway在应用程序启动时迁移数据库。3.Flyway的工作机制Flyway需要先在DB中创建一个元数据表(默认表名为flyway_schema_history),其中保存了每条迁移(migration)记录,记录中包含了迁移脚本的版本号和SQL脚本校验和值。下图表示多个数据库版本。对应的元数据表记录:installed_rankversiondescriptiontypescriptchecksuminstalled_byinstalled_onexecution_timesuccess11InitialSetupSQLV1__Initial_Setup.sql1996767037axel2016-02-0422:23:00.0546true22FirstChangesSQLV2__First_Changes.sql12501axel-48202-0609:18:00.0127trueFlyway扫描文件系统或应用程序的类路径以读取DDL和DML以进行迁移。根据元数据表检查迁移。如果脚本声明的版本号小于或等于标记为当前的版本号之一,它们将被忽略。剩余的迁移是待处理的迁移:可用,但未应用。最后按版本号排序依次执行,并将执行结果写入元数据表。对应的元数据表记录:installed_rankversiondescriptiontypescriptchecksuminstalled_byinstalled_onexecution_timesuccess11InitialSetupSQLV1__Initial_Setup.sql1996767037axel2016-02-0422:23:00.0546true22FirstChangesSQLV2__First_Changes.sql12501axel-48202-0609:18:00.0127trueFlyway支持命令行(需要下载命令行工具)和JavaApi,还支持构建工具Maven和Gradle。这里我们主要关注JavaApi。3.Flyway规则Flyway如何比较两个SQL文件的顺序?采用左对齐原则,缺的用0代替。举几个例子:1.0.1.1是比1.0.1晚的版本。1.0.10是比1.0.9.4更高的版本。1.0.10与1.0.010一样高的版本号,每个版本号部分的前导0被忽略。Flyway将SQL文件分为三种类型:Versioned、Repeatable和Undo:Versioned用于版本升级,每个版本都有唯一的版本号,只能执行一次。Repeatable可以重复执行,当Flyway检测到Repeatable类型的SQL脚本的校验和有变化时,Flyway会重新应用该脚本。它不用于版本更新,这种类型的迁移总是在执行Versioned之后执行。撤消用于撤消具有相同版本的版本化迁移的影响。但是回滚过于粗糙,过于机械化,所以一般不推荐。一般建议使用Versioned模式来解决。这三种命名规则如下图所示:Prefix是可配置的,前缀标识,默认值V表示Versioned,R表示Repeatable,U表示UndoVersion标识版本号,由一个或多个数字组成,数字之间的分隔符可以是一个点。或下划线_分隔符可配置,用于分隔版本标识和描述信息,默认为两个下划线__描述描述信息,文本可通过下划线_或空格分隔后缀可配置,后续标识,默认为.sql4。SpringBoot集成FlywaySpringBoot提供了Flyway的自动配置。允许我们使用Flyway开箱即用地进行数据库版本控制。4.1Flyway依赖只需要引入依赖:org.flywaydbflyway-core当然可以您需要集成您的关系数据库环境。这里我们使用H2数据库来演示,其他的数据库都是一样的,只是方言不同而已。对H2数据库不熟悉的可以参考我的专题文章SpringBoot2实战:H2数据库集成与使用。4.2Flyway配置为了直观说明配置,首先在SpringBoot配置文件application.yml中,我们配置H2数据库为:spring:datasource:#h2driverdriver-class-name:org.h2.Driver#h2的数据库持久化到磁盘D:/h2libraryname:flywaymysqlmodeurl:jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUEh2:#Enableconsoleaccessdefaultfalseconsole:enabled:truesettings:#Enableh2console跟踪方便调试defaultfalsetrace:true#允许控制台远程访问defaultfalseweb-allow-others:true#h2访问路径contextpath:/h2-console对应Flyway配置:#flyway配置spring:flyway:#启用或禁用flywayenabled:true#flyway'sclean该命令将删除指定模式下的所有表,必须在生产中禁用。默认值false作为默认配置理论上是不科学的。clean-disabled:true#SQL脚本目录,多个路径用逗号分隔默认值classpath:db/migrationlocations:classpath:db/migration#metadata版本控制信息表defaultflyway_schema_historytable:flyway_schema_history#如果没有flyway_schema_history元数据表,执行之前flywaymigrate命令,必须先执行flywaybaseline命令#设置为true,然后flyway会在需要基线的时候自动执行基线。baseline-on-migrate:true#指定baseline的版本号,默认值为1,迁移时会忽略低于此版本号的SQL文件baseline-version:1#字符编码默认为UTF-8encoding:UTF-8#允许乱序迁移吗?开发建议true生产建议falseout-of-order:false#需要flyway控制的Schemalist,这里我们配置为flyway默认,使用spring.datasource.url配置的schema,#可以指定多个schema,但只能指定元数据表将在第一个模式下创建,并且migrationsql脚本将仅应用于第一个模式。#但是flywayClean命令会在这些schema下依次执行。所以一定要产生spring.flyway.clean-disabledtrueschemas执行迁移时是否自动调用validation:flyway#当你的版本不符合逻辑时,比如先执行DML,没有对应的DDL,就会抛出异常被抛出validate-on-migrate:true请务必仔细阅读Flyway相关配置说明。4.3编写SQL初始化脚本我们首先编写一个初始化SQL文件,在H2数据库中已经自动初始化的schemaflyway中添加一个sys_user表。注意命名约定。脚本名称是V1.0.1__Add_table_user.sql。SQL脚本的位置配置在spring.flyway.locations下。内容是:use`flyway`;CREATETABLE`sys_user`(`user_id`int(10)unsignedNOTNULLAUTO_INCREMENT,`username`varchar(1024)NOTNULLunique,`encode_password`varchar(1024)NOTNULL,`age`int(3)NOTNULL,PRIMARYKEY(`user_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;insertintoflyway.sys_uservalues(1,'Felordcn','{noop}12345',18);启动SpringBoot应用。打开H2数据库控制台http://localhost:8080/h2-console,在JDBCURL栏中粘贴jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE,点击Connect按钮进入如下Interface:这里-??1是因为我们默认了Flyway需要的flyway_schema_history表。0是因为H2数据库会自动初始化Schemaflyway,其他数据库可能需要你手动创建。4.4编写SQL更改脚本我们编写一个V1.0.0__Delete_sysuser_felordcn.sql来删除V1.0.1__Add_table_user.sql中初始化的用户。你会发现启动报错,因为我们开启了验证,所以对于逻辑错误的版本会抛出异常。我们修改版本号为V1.0.2__Delete_sysuser_felordcn.sql,重新启动。通过H2数据库控制台,我们会发现多了一条变化记录:与此同时,sys_user表中的数据也没有了,符合预期。5.Flyway最佳实践通过以上介绍,相信大家很快就会使用Flyway进行数据库版本控制。这里总结一些实际开发中的经验:spring.flyway.cleanDisabled=false在生产中必须禁用。尽量避免使用撤消模式。开发版本号尽量按照团队命名,以免混淆。比如V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql,这种命名方式也可以获取更多的脚本开发者和相关功能的信息。spring.flyway.outOfOrder的值对于生产为真,对于开发为假。当多个系统共享一个数据库模式时,配置spring.flyway.table为不同的系统设置不同的元数据表名,而不是使用默认值flyway_schema_history。6.小结今天介绍了Flyway数据库版本迁移管理工具,并结合SpringBoot。这将大大规范我们的数据库管理,提高生产效率。同时也分享了一些非常有用的生产实践经验。