1、简单介绍一下flyway
flyway 是一款开源的数据库版本控制工具,主要用于管理数据库结构的变更(如创建表、修改字段、插入数据等)。它通过跟踪和执行版本化的迁移脚本,帮助团队实现数据库变更的自动化。接下来简单介绍一下flyway的工作流程:
1.1、 初始化阶段
检查元数据表
flyway 首先检查目标数据库中是否存在 flyway_schema_history
表(默认表名称,也可以自定义历史表名称)。
- 不存在:自动创建该表,用于记录迁移历史
- 已存在:读取已有迁移记录
千万不要手动的修改历史表的任何数据,不然肯定会导致版本管理错误。
1.2、 迁移扫描
脚本加载
扫描配置的 locations
路径(默认 classpath:db/migration
),识别两类脚本:
- 版本化迁移脚本(
v
开头) - 可重复迁移脚本(
r
开头)
1.3、校验阶段
校验 checksum
对比已执行脚本的 checksum
与本地文件的 checksum
:
- 若已执行脚本的 checksum 发生变化 → 抛出错误(防止篡改历史脚本)
- 校验通过 → 进入迁移阶段
1.4、 迁移执行
版本化迁移
按版本号顺序执行所有 未应用 的 v
前缀脚本,且 仅执行一次
可重复迁移
按文件名顺序执行 r
前缀脚本,当脚本内容变化时 重新执行
1.5、 更新元数据
每个成功执行的脚本会被记录到 flyway_schema_history
表,包含:
版本号
脚本名称
checksum
执行时间
执行状态
如图就是一个默认的历史表中数据。
在这里详细解释一个flyway中的两种字母开头的执行脚本的不同;
v
开头 vs r
开头脚本的区别
1. 版本化迁移脚本(v
前缀)
命名规则v<version>__<description>.sql
(例如 v1.2__create_user_table.sql
)
version
:唯一且不可变的版本号(建议使用语义化版本,如1.0.1
)description
:人类可读的描述(使用下划线分隔单词)
核心特性
一次性执行:每个脚本仅执行一次
顺序敏感:按版本号顺序依次执行
内容不可变:已执行的脚本内容不可修改(否则校验失败)
典型场景
- 创建/修改表结构
- 新增索引或约束
- 一次性数据迁移(如初始化基础数据)
2. 可重复迁移脚本(r
前缀)
命名规则r__<description>.sql
(例如 r__update_product_view.sql
)
- 没有版本号
description
:描述脚本作用(按字母顺序排序执行)
核心特性
- 重复执行:脚本内容变化时自动重新执行
- 顺序依赖:按文件名字母顺序执行
- 内容可变:允许修改后重新应用
典型场景
- 维护视图(view)或存储过程(stored procedure)
- 更新静态数据(如多环境差异化配置)
- 重建索引或物化视图
关键对比总结
特性 | v 前缀脚本 | r 前缀脚本 |
---|---|---|
执行次数 | 仅一次 | 内容变化时重复执行 |
版本号 | 必须唯一且递增 | 无版本号 |
内容修改 | 禁止修改(会导致校验失败) | 允许修改(触发重新执行) |
执行顺序 | 按版本号顺序 | 按文件名字母顺序 |
适用场景 | 结构变更、一次性操作 | 可重复逻辑、数据维护 |
最佳实践建议
版本化脚本 (v)
- 使用语义化版本(如
v1.2.3
) - 每个脚本完成一个独立的变更任务
- 禁止修改已提交到代码仓库的
v
脚本
可重复脚本 (r)
- 用于维护视图、存储过程等易变对象
- 通过文件名控制执行顺序(如
r__01_viewa.sql
,r__02_viewb.sql
) - 谨慎修改生产环境的
r
脚本(可能触发全量更新)
混合使用策略
- 用
v
脚本管理表结构变更 - 用
r
脚本管理视图和存储过程
示例:
db/migration/ ├── v1.0__create_tables.sql ├── v1.1__add_indexes.sql └── r__update_views.sql
校验保护
- 生产环境务必启用
validate-on-migrate: true
- 开发环境可开启
flyway.validate-migration-naming: true
强制命名校验
通过合理使用 v
和 r
脚本,可以实现数据库变更的 原子性 和 可追溯性,同时适应不同场景的灵活性需求。
2、使用spring boot项目整合flyway
2.1、新创建一个spring boot项目,并导入一些初始的依赖;
<dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.flywaydb</groupid> <artifactid>flyway-core</artifactid> <!-- 无需指定版本(spring boot 已管理) --> </dependency> <!-- druid连接池 --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid-spring-boot-starter</artifactid> <version>1.2.18</version> </dependency> <!-- mysql--> <dependency> <groupid>com.mysql</groupid> <artifactid>mysql-connector-j</artifactid> </dependency> <!-- 无需指定版本(spring boot 已管理) --> <dependency> <groupid>org.flywaydb</groupid> <artifactid>flyway-mysql</artifactid> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>true</optional> </dependency> <dependency> <groupid>org.mybatis.spring.boot</groupid> <artifactid>mybatis-spring-boot-starter</artifactid> <version>3.0.3</version> </dependency> </dependencies>
需要注意的一点是,spring官方自动管理的flyway的版本,所以我们只需要指定spring的版本就自动会兼容合适的flyway版本,我的spring boot版本为3.3.9
我们主要使用到的依赖有三个:
flyway-core:flyway的核心依赖
flyway-mysql:指定数据库的类型
mybatis-spring-boot-starter: 数据源的自动配置,也可以是其他的依赖坐标。不一定要是mybatis,如jdbc、jpa等都可以
2.2、配置相应的yml配置文件
spring: datasource: type: com.alibaba.druid.pool.druiddatasource driver-class-name: com.mysql.cj.jdbc.driver url: jdbc:mysql://localhost:3306/testflyway?useunicode=true&characterencoding=utf-8&usessl=false&servertimezone=utc username: root password: 123456 flyway: enabled: true locations: ["classpath:db/migration"] # 修正为数组格式 table: flyway_schema_history baseline-on-migrate: true # 必须启用(处理已有表场景) sql-migration-prefix: "v" sql-migration-separator: "__" sql-migration-suffixes: [".sql"] # 数组格式 logging: level: org.flywaydb: trace # 输出最详细日志
我们只需要配置一些flyway的属性,就可以直接使用flyway了。
2.3、编写相应的sql执行语句,并且存放在固定的文件地址
-- 创建用户表 create table if not exists user ( id int auto_increment primary key, username varchar(50) not null unique, email varchar(100) not null, created_at timestamp default current_timestamp ); -- 初始数据插入 insert into user (username, email) values ('admin', 'admin@example.com'), ('user1', 'user1@example.com');
我这里就创建了一张数据表,并且插入了一些数据;
将sql脚本放在合适的位置:
注意sql脚本的存放位置不是乱放的,要符合我们之前在yml配置文件中书写的配置,sql脚本的名称也不是随便取得,要符合flyway的命名规范。
2.4、运行spring boot项目
我们配置好了这些之后,就可以直接启动spring boot项目了。如果你是第一次启动项目,flyway会自动扫描相应文件夹下的sql脚本,并在你的数据库中建立一个历史记录表 flyway_schema_history。要特别注意的是我们千万不要手动的修改这张表中的任何数据,flyway就是根据这张历史记录表来进行sql脚本的执行等等一系列操作。
我们可以直接在控制台中看到flyway已经顺利的执行我们相应的sql脚本
我们现在可以连接一下数据库来看看是否正确
可以看到数据库中已经有了相应的数据表,并且数据表中已经有了一些初始数据了
这个是我们第一次启动spring boot项目时自动执行的sql脚本。那么等我们第二次启动时,flyway还是会扫描相应的sql脚本,同时查询 flyway_schema_history
历史表,来判断sql脚本要不要执行。当我们在此运行spring boot项目:
我们在控制台的日志中可以很清楚的看到flyway的执行过程。
3、总结
以上,就是我们使用spring boot整合flyway来进行数据库的版本管理。总体来说是非常简单的,我们只需要一些简单的配置和遵守一些flyway的命名规定就可以直接使用flyway了。这也是spring官方一直在努力推行的
约定大于配置,配置大于编码
当然,flyway的功能还有很多,这篇文章也只是初步帮你认识一下flyway。并且使用spring boot来简单的使用flyway的基本功能,但总的来说,我们几乎可以只通过一些配置文件中属性来使用flyway的绝大部分功能,一下我整理了一些常用的flyway属性,供大家参考:
spring: flyway: # 基础配置 enabled: true # 是否启用 flyway,默认 true url: jdbc:mysql://localhost:3306/db # 覆盖默认数据库连接(可选) user: root # 覆盖默认数据库用户(可选) password: root # 覆盖默认数据库密码(可选) # 脚本管理 locations: # 迁移脚本路径(默认 classpath:db/migration) - classpath:db/migrations - filesystem:/opt/migrations encoding: utf-8 # 脚本文件编码,默认 utf-8 sql-migration-prefix: v # 版本迁移脚本前缀,默认 "v" repeatable-sql-migration-prefix: r # 可重复迁移脚本前缀,默认 "r" sql-migration-separator: __ # 脚本名称分隔符,默认双下划线 sql-migration-suffixes: # 脚本后缀列表,默认 [".sql"] - .sql - .pgsql # 迁移规则 schemas: public # flyway 管理的 schema 列表(逗号分隔) table: flyway_history # 元数据表名,默认 "flyway_schema_history" baseline-on-migrate: false # 迁移时自动执行基线(默认 false) baseline-version: 1 # 基线版本号,默认 "1" baseline-description: initial setup # 基线描述 target: latest # 目标版本(默认最新版本,可用版本号如 "3.1") out-of-order: false # 是否允许乱序执行迁移(默认 false) validate-on-migrate: true # 迁移时校验脚本(默认 true) ignore-missing-migrations: false # 忽略缺失的迁移记录(默认 false) # 占位符配置 placeholder-replacement: true # 启用占位符替换(默认 true) placeholders: # 自定义占位符键值对 key1: value1 key2: value2 # 高级配置 clean-on-validation-error: false # 校验失败时自动执行 clean(危险!默认 false) connect-retries: 3 # 连接失败重试次数(默认 0) lock-retry-count: 50 # 获取锁的重试次数(默认 50) group: false # 将相同版本的迁移合并为单个事务(默认 false) mixed: false # 是否允许混合 ddl 和 dml(默认 false) skip-default-callbacks: false # 跳过默认回调(默认 false) skip-default-resolvers: false # 跳过默认解析器(默认 false) init-sqls: # 获取连接后立即执行的 sql 语句 - set role 'myuser' # 多环境配置示例 --- spring: profiles: prod flyway: url: jdbc:mysql://prod-db:3306/prod_db locations: - "classpath:db/migration/common" - "classpath:db/migration/prod" ignore-migration-patterns: "*:pending"
关键配置说明:
基础配置:默认会复用 spring.datasource
配置,需要覆盖时单独指定
脚本管理:通过前缀/后缀/路径控制脚本识别规则
迁移规则:控制基线、校验、执行顺序等核心行为
生产环境注意事项:
clean-on-validation-error
应始终保持false
out-of-order
需谨慎启用- 建议明确指定
target
版本控制生产环境迁移
最佳实践:
- 使用 classpath 和 filesystem 组合路径管理脚本
- 通过 placeholders 实现环境差异化配置
- 启用校验确保迁移安全
可以通过 flyway.validatemigrationnaming 配置项(默认 false)开启严格的脚本命名校验,建议开发环境开启。
flyway的官网地址为:https://flywaydb.org/
你有如果想了解更多有关flyway的信息,可以直接访问官网
到此这篇关于spring boot整合flyway实现数据的动态维护的示例代码的文章就介绍到这了,更多相关springboot flyway数据动态维护内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论