从零搭建 Spring Boot 后端项目(十二)

简介

多人同时开发后端时,数据表的创建和修改会显得格外头痛,因为mybatis只能先建数据表,再用逆向工程生成类。如数据表修改后,多人未做即时沟通,那么代码就会乱,那有什么东西办法解决吗,有,那就是数据库版本控制工具-----Flyway,不只方便多人合作,更可以支持数据库的版本控制,和数据库的迁移。使用Flyway,用户可以从任意一个数据库版本迁移到最新版本,简单而且有效

Flyway介绍

Flyway是一个开源的数据库迁移工具。相对于配置,它更倾向于简单和约定。它基于7个基本命令: MigrateCleanInfoValidateUndoBaselineRepair。有命令行客户端也可以用Java API操作,Maven插件或Gradle插件操作也可以,如果还不够,好消息是还可以与 Springboot 集成,只需导入依赖即可在启动项目时,自动使用迁移

迁移概念

使用Flyway,对数据库的所有更改都称为迁移,迁移可以是版本化的,也可以是可重复的。版本化迁移有两种形式:常规迁移撤销迁移。版本化的迁移有版本、描述和校验和,版本必须是唯一的。该描述仅提供信息,以便您能够记住每个迁移所做的工作,校验和用于检测意外变化,版本化迁移是最常见的迁移类型,它们只按顺序应用一次。也可以通过提供具有相同版本的撤销迁移来撤消它们的效果。可重复迁移有描述和校验和,但没有版本。它们不再只运行一次,而是在每次校验和发生变化时(重新)应用它们。在一次迁移运行中,可重复迁移总是在所有挂起的版本化迁移都已执行之后最后应用,可重复的迁移是按照描述的顺序应用的。默认情况下,版本化的和可重复的迁移都可以用SQL或Java编写,并且可以由多个语句组成。Flyway自动发现文件系统和Java类路径上的迁移。为了跟踪已经在何时以及由谁应用了哪些迁移,Flyway向您的模式添加了一个模式历史表必须为每个版本化的迁移分配一个唯一的版本,对于大多数情况,您只需要一个简单的递增整数,但是为了不与同组人员重复且更有意义,建议采用此日期形式:年月日时分秒,例如:2020.07.29.10.51.01或20200729.10.51.01

常用命令
  • migrate 此命令会搜索默认的脚本目录,而后根据脚本迁移更新数据表,如脚本与数据库版本一致,则不迁移
  • clean 此命令会清除指定schema下所有内容,开发、测试方便,但生产必须禁止,危险
  • info 打印关于所有迁移的详细信息和状态信息,可以看到哪些迁移已经应用,哪些在等待,以及是否成功等
  • validate 验证应用于数据库的迁移与本地可用的脚本是否匹配,Flyway 的 Migration 会默认先做 Validate
  • undo 撤销最近应用的版本化迁移 (注:有破坏性的改变(删除,删除,截断,…)时,撤销实践会失败,能不用就不用此命令)
  • baseline 为现有数据库建立基线,排除掉baselineVersion前的所有迁移,且包括baselineVersion,而后再迁移最新的版本
  • repair 修复schema历史表, 修复场景有:1. 移除失败的 migration 记录 2.已经应用的 SQL 脚本被修改后,重新应用该 SQL 脚本
脚本命名

Flyway会自动扫描配置路径下的脚本文件(默认为:resources/db/migration),并进行迁移,但这里的脚本命令方式有规范:
从零搭建 Spring Boot 后端项目(十二)_第1张图片
文件名由以下部分组成:

  • Prefix(前缀)V表示版本化(可配置),U表示撤消(可配置),R表示可重复迁移(可配置)
  • Version(版本号):使用点或下划线的版本号可以根据您的需要分隔成许多部分(建议使用:年月日.时.分.秒 格式)
  • Separator(分隔符)__ (两个下划线)(可配置)
  • Description(描述):用下划线或空格分隔的一串单词
  • Suffix(后缀). sql(可配置)
命名实践

这里给一些脚本命名最佳实践的一些意见:

  • 开发环境和生产环境的migration SQL不共用。因为开发下脚本会很多,迁移频繁,生产下直接把脚本手动打包,升级时再写脚本即可
  • 建议用时间戳作为版本号,多人一起开发不会导致版本号争用,同时再加上生产环境的版本号,这样的话, 将来手工打包成生产环境比较方便,例如:V20200729.10.51.01__V1.0_Add_Create_Person_Table.sql
  • migration 后的SQL 脚本不应该再被修改
  • 开发环境下spring.flyway.outOfOrder=true,能加载漏掉的老版本sql文件,生产环境下应该设置 false
Schema 历史表

为了跟踪在何时以及由谁应用了哪些迁移,Flyway向您的模式添加了一个特殊的Schema历史表。您可以将此表看作对模式执行的所有更改的完整记录,它还跟踪迁移校验和以及迁移是否成功,默认表名为:flyway_history_schema 。其中包括的内容有:版本号描述脚本类型脚本名称校验和(checksum)、抛行人抛行时间执行次数成功与否
注:checksum是算法根据脚本文件生成的校验和,如果是脚本文件改变校验和就会变,以此判断文件是否变化

错误提示

当Flyway执行SQL语句时,它报告数据库返回的所有警告。如果返回一个错误,Flyway会显示它和所有必要的细节,将迁移标记为失败,并在可能的情况下自动回滚,例如:

Migration V1__Create_person_table.sql failed
--------------------------------------------
SQL State  : 42001
Error Code : 42001
Message    : Syntax error in SQL statement "CREATE TABLE1[*] PERSON "; expected "OR, FORCE, VIEW, ...
Location   : V1__Create_person_table.sql (/flyway-tutorial/V1__Create_person_table.sql)
Line       : 1
Statement  : create table1 PERSON
工作原理

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

步骤

  • 接下来把Flyway整合进项目,先在resources目录下新建目录db\migration,用来存sql脚本
  • 在pom.xml文件下添加以下依赖
        
        
            org.flywaydb
            flyway-core
            6.5.0
        
  • 在application-dev.properties配置文件下,添加以下配置
# Flyway
# 是否启用Flyway
spring.flyway.enabled=true
# clean命令会删除指定schema下所有内容,所以生产时必须禁掉
spring.flyway.cleanDisabled=false
# 设定sql脚本的目录,多个路径使用逗号分隔
spring.flyway.locations=classpath:db/migration
# 检查迁移脚本的目录是否存在
spring.flyway.check-location=true
# 最大的重试次数
spring.flyway.connect-retries=0
# 设置编码
spring.flyway.encoding=UTF8
# 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移
spring.flyway.baseline-on-migrate=true
# 指定该版本与该版本之下的,migrate的时候会被忽略
spring.flyway.baselineVersion=0
# 迁移时是否校验
spring.flyway.validate-on-migrate=true
# 设定Flyway的metadata表名
spring.flyway.table=flyway_schema_history
# 需要Flyway管控的schema
spring.flyway.schemas=backend_template
# 是否允许无序的迁移
spring.flyway.out-of-order=false
  • 这里如果我们从一开始就整合了Flyway,那么现在就可以直接在db/migration目录下写SQL脚本开发了,但现在已经有数据库backend_template了,属于中途加入Flyway,这里的解决方法有两种:第一种: 生成SQL脚本后,删除原backend_template库,新建backend_template空库,启动项目,SpringBoot和Flyway会用原脚本自动生成backend_template数据库,但这里有个问题,即此项目权限那块要数据库里的表,所以这里不好演示,我们知道即可。第二种: 生成脚本后,不动原数据库,以现数据库为基准,继续开发即可。故先把现在的数据手动导成SQL文件吧,首先点击IDEA下的Terminal按钮(当然也可以进入命令行到项目指定目录)
    从零搭建 Spring Boot 后端项目(十二)_第2张图片
  • 然后进入src\main\resources\db\migration目录
cd src\main\resources\db\migration
  • 用mysql命令把backend_template数据库导出成sql文件,存入db\migration目录,注意命名规范
mysqldump -uroot -p backend_template > .\V20200729.16.00.00__V1.0_Init_Database.sql
  • 接着刷新一下目录db\migration,就可以看到V20200729.16.00.00__V1.0_Init_Database.sql脚本文件了
    在这里插入图片描述
  • 启动项目,此时,Flyway就会以现有数据库为基准,并且会生成元数据表了
    从零搭建 Spring Boot 后端项目(十二)_第3张图片
  • 新建的 flyway_schema_history 数据表的内容如下 :
    在这里插入图片描述
  • 至此,flyway就整合成功了,内容很简单,但功能很强大,我们接下来开发,数据表的改变只用在db\migration目录下写脚本就可以了,示例,我们新建一张people表,首先在db\migration目录下新建文件,文件名为
V20200729.18.00.00__V1.0_Add_table_people.sql
  • 然后再文件名中输入以为SQL脚本
create table people
(
	id INT auto_increment,
	name VARCHAR(255) null,
	age int null,
	constraint people_pk
		primary key (id)
);
  • 最后运行一下项目,这张表就创建好了
    从零搭建 Spring Boot 后端项目(十二)_第4张图片

项目地址

项目介绍:从零搭建 Spring Boot 后端项目
代码地址:https://github.com/xiaoxiamo/backend-template

你可能感兴趣的:(后端模板,flyway,java)