在日常开发中,我们可能经常遇到这样的问题,由于项目需求的变化,或者前期需求设计不完善,导致在后期需要修改已经设计好的数据库表结构。如果是一个新开发的项目,还处于开发阶段,新增字段还好,但是如果是调整某些字段,是不是有点奔溃呢?是不是会考虑过把需要调整的表删除了重新创建呢?
目前对于数据库版本进行管理的工具,主要有两个:Flyway、Liquibase
。对于 Liquibase
本文不做过多介绍,了解就好。下面主要介绍一下 Flyway
。
Flyway官网地址:https://flywaydb.org/getstarted/how
对于在一个全新的SpringBoot
项目中,如何使用 Flyway
呢?这个很简单,只需要在新建项目时,勾选一下 Flyway
选项就可以使用,具体操作如下图:
当项目创建成功后,可以看一下 pom.xml
文件里会自动加上 Flyway
的依赖,并且会在 resources
目录下自动创建一个 db/migration
目录,这个目录用来存放数据库脚本的,具体如如下:
如果要在已有项目或者模块中使用 Flyway
,步骤和上面的一样。只不过手动操作上面两步,第一步要在pom.xml
中添加flyway
的依赖,如下所示:
<dependency>
<groupId>org.flywaydbgroupId>
<artifactId>flyway-coreartifactId>
dependency>
第二步在对应的项目或者模块下的 resources
目录下,手动创建 db/migration
目录即可。
当我们经过上面两步后,我们需要在db/migration
目录下创建数据库脚本文件,脚本文件的命名方式如下:
V__.sql
说明:首先是大写字母 V,然后是版本号,要是有小版本可以用下划线隔开,例如 3_1,版本号后面是两个下划线,然后是脚本名称,文件后缀是 .sql。
举个例子:现在需要创建 test数据库
(第一次创建),数据库中包含3个表,数据库脚本文件的名称如下。我们只需要把test数据库中所有的建表语句以SQL
的形式导出,拷贝到下面的文件中就可以了。
V1__test.sql
完了之后,不用添加额外配置,只需要在 MySQL
中创建一个空的 test
数据库即可,然后直接启动项目,项目启动成功后,就会自动帮我们把所有表都创建好。
当我们启动项目时,可以发现数据库脚本会被执行,同时 Flyway
还给创建了一个 flyway_schema_history
表,这个表是Flyway
自己创建的,用来记录数据库的更新历史。我们可以看一下这表的具体结构:
有了这条记录,下次再启动项目,V1__test.sql 这个脚本文件就不会执行了,因为系统知道这个脚本已经执行过了,如果你还想让 V1__test.sql 脚本再执行一遍,需要手动删除 flyway_schema_history 表中的对应记录,那么项目启动时,这个脚本就会被执行了。
脚本执行细节说明
我们在定义脚本的时候,除了 V 字开头的脚本之外,还有一种 R 字开头的脚本,V 字开头的脚本只会执行一次,而 R 字开头的脚本,只要脚本内容发生了变化,项目启动时脚本就会被重新执行。
使用了 Flyway
之后,如果再想进行数据库版本升级,就不用修改以前的数据库脚本了,直接创建新的数据库脚本,项目在启动时检测了有新的更高版本的脚本,就会自动执行。
所有的脚本,一旦执行了,就会在 flyway_schema_history
表中有记录,如果你不小心搞错了,可以手动从 flyway_schema_history
表中删除记录,然后修改 SQL
脚本后再重新启动。
在 Spring Boot 中,关于 Flyway 也有不少配置,这些配置都在 application.properties 中进行配置,常用的几个来和大家说下:
指定是否开启 flyway,默认就是开启的;
指定 flyway 字符编码;
sql 脚本的目录,默认是 classpath:db/migration,如果有多个,用逗号隔开;
配置数据库信息表的名称,默认是 flyway_schema_history;
这个属性很重要,它表示是否要清除已有库下的表,如果执行的脚本是 V1__xxx.sql,那么会先清除已有库下的表,然后再执行脚本,而且它默认就是要清除,生产环境一定要自己配置设置为 true。
脚本命名方式补充
$PREFIX$VERSION__$REMARK.$SUBFIX
$preifx表示前缀,可在配置中指定,默认为 V
$version 表示版本,中单可以使用 . 或 _分隔,在解析时会将_转换为.保存到fly_schema_history
表的version
字段中;
$remark 表示备注,解析后会将这部分写入到description字段中;
$subfix 表示后缀,可在配置中指定,默认为.sql;
版本与描述之前使用__分隔(双下划线)