引言
小伙伴们,大家好,你们在做项目迭代时,用的什么工具管理数据库表 DDL 和 DML 变更的?怎么把开发环境的 SQL 变更同步到生产环境?今天介绍一下使用 flyway 管理我们的数据库版本,帮你轻松管理 SQL 版本。
P.S. 在公司内部项目上,我们用的是 阿里云DMS 管理,数据库申请、结构设计、数据变更&审批、查询都在 DMS 上完成,功能非常贴心。
快速使用
spring boot 3.x 集成 flywaydb
咱们要达到的效果:每次迭代开发阶段,把变更的 DDL 和 DML 写到 SQL 文件中,应用启动时,可以自动检查 SQL,并执行到数据库中。推进迭代到生产环境时,可以自动把 SQL 变更执行到生产库中。
引入依赖
在 pom.xml
或者 build.gradle
文件引入依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.1.0</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>10.1.0</version>
</dependency>
如果项目中使用的是其他类型的数据库,替换一下 flyway-mysql
为 flyway-数据库
,当前支持的数据库包括 flyway-database-postgresql、flyway-sqlserver、flyway-database-oceanbase等,更多依赖,可查看 flyway 的 maven 仓库。
:::success
💡 flyway 支持常见的数据库版本,查看官方文档了解更多...
:::
配置
在配置文件application.yml
或 application.properties
中配置 flyway 的参数。
spring:
# flyway 依赖数据源
datasource:
url: jdbc:mariadb://localhost:3306/ranmai
# flyway 的配置
flyway:
enabled: true
baselineOnMigrate: true
validateOnMigrate: true
baselineVersion: 1.0.0
locations: classpath:db/migration
如上配置字段表示:
flyway.enabled:
是否打开 flyway 数据 SQL 迁移的开关flyway.baselineOnMigrate:
是否自动执行基线版本的开关flyway.validateOnMigrate:
执行 SQL 迁移时,是否校验 SQL 的有效性和签名地址是否正确flyway.baselineVersion:
基线版本,可以不设置flyway.location:
要迁移的 SQL 在哪个文件夹spring.datasource.xx:
数据源的配置,flyway 做数据迁移时,需要使用数据源
完整的 flyway 配置,可以查看文件
org.springframework.boot.autoconfigure.flyway.FlywayProperties
写迁移的 SQL
在配置的 SQL 迁移的文件夹中,写每次迭代变更的 SQL文件,一次迭代可以写多个,文件名格式为V{版本号}__{描述信息}.sql
比如:
V1.0.0__initSchema.sql
# create table setting
create table if not exists sys_setting
(
id bigint auto_increment primary key,
gmt_create timestamp default CURRENT_TIMESTAMP not null comment '创建时间',
gmt_modified timestamp default CURRENT_TIMESTAMP not null comment '更新时间',
code varchar(32) not null comment '配置编码',
value varchar(1000) not null comment '配置值'
);
V1.0.1__updateDataType.sql
# update sys_setting value to text.
alter table sys_setting
modify column value text;
执行
启动Spring Boot应用,查看执行日志,是否有如下信息,如果有,说明执行成功。
2024-08-13 11:52:12 [INFO][com.zaxxer.hikari.HikariDataSource:122]: HiKariPool - Start completed.
2024-08-13 11:52:12 [INFO][org.flywaydb.core.FlywayExecutor:37]: Database: jdbc:mysql://localhost:3306/ranmai (MySQL 8.4)
2024-08-13 11:52:12 [WARN][o.f.c.i.database.base.Database:41]: Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.
2024-08-13 11:52:12 [INFO][o.f.core.internal.command.DbValidate:37]: Successfully validated 2 migrations (execution time 00:00.043s)
2024-08-13 11:52:12 [INFO][o.f.core.internal.command.DbMigrate:37]: Current version of schema `ranmai`: << Empty Schema >>
2024-08-13 11:52:12 [INFO][o.f.core.internal.command.DbMigrate:37]: Migrating schema `ranmai` to version "1.0.0 - initSchema"
2024-08-13 11:52:12 [INFO][o.f.core.internal.command.DbMigrate:37]: Migrating schema `ranmai` to version "1.0.1 - updateDataType"
2024-08-13 11:52:12 [INFO][o.f.core.internal.command.DbMigrate:37]: Successfully applied 2 migrations to schema `ranmai`, now at version v1.0.1 (execution time 00:00.122s)
或者查看数据库表 flyway_schema_history�
是否有执行记录
如果下次执行,flyway 会检查
flyway_schema_history�
中是否有执行记录,对应 SQL 文件的校验和是否一致,如果不一致会报错,如果一致会忽略该版本的执行。
:::success
💡 flyway 执行记录在 flyway_schema_history 表中,该表 flyway 会自动创建。
:::
集成 flyway maven 插件
在 pom.xml
文件中,引入配置
<project xmlns="...">
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>10.1.0</version>
<configuration>
<!-- 数据源相关的配置 -->
<url>jdbc:h2:file:./target/foobar</url>
<user>sa</user>
</configuration>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
同上步中,写好 SQL 迁移脚本,然后执行命令
mvn flyway:migrate
还是集成到 spring boot 中,用起来比较方便 😄
FAQ
多人添加SQL,导致出现同版本的 SQL脚本,执行冲突
团队多人一起做一个项目时,在开发环境很容易出现该问题,如果出现,后添加的 SQL 脚本文件,升级一下版本号,在继续执行即可。
已执行 SQL 文件变更SQL 内容,提示校验和不通过?
启动应用时,报错
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 1.0.0
-> Applied to database : -1794293023
-> Resolved locally : -1901383139
Either revert the changes to the migration, or run repair to update the schema history.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
解决:
1、先确认有冲突 SQL 是否有变更,如果有变更,通过添加新版本变更
2、快速解决方法,可以修改表 flyway_schema_history
中修改对应版本的 checksum
的值,改成最新的值,在确认无影响的前提下,再修改
select * from flyway_schema_history where version = '1.0.0';
flyway 没有 starter 包,怎么自动执行的呢
spring-boot-autoconfigure
包已经包含了 Flyway 的自动化配置.当配置参数中有spring.flyway.enabled=true
而且有 Flyway.class
和FlywayDataSourceCondition.class
类时,就会自动触发 Flyway 的配置。
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
@ConditionalOnClass(Flyway.class)
@Conditional(FlywayDataSourceCondition.class)
@ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true)
@Import(DatabaseInitializationDependencyConfigurer.class)
@ImportRuntimeHints(FlywayAutoConfigurationRuntimeHints.class)
public class FlywayAutoConfiguration {
...
}