spring boot整合flyway實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)維護(hù)的示例代碼
1、簡(jiǎn)單介紹一下flyway
Flyway 是一款開源的數(shù)據(jù)庫(kù)版本控制工具,主要用于管理數(shù)據(jù)庫(kù)結(jié)構(gòu)的變更(如創(chuàng)建表、修改字段、插入數(shù)據(jù)等)。它通過(guò)跟蹤和執(zhí)行版本化的遷移腳本,幫助團(tuán)隊(duì)實(shí)現(xiàn)數(shù)據(jù)庫(kù)變更的自動(dòng)化。接下來(lái)簡(jiǎn)單介紹一下flyway的工作流程:
1.1、 初始化階段
檢查元數(shù)據(jù)表
Flyway 首先檢查目標(biāo)數(shù)據(jù)庫(kù)中是否存在 flyway_schema_history 表(默認(rèn)表名稱,也可以自定義歷史表名稱)。
- 不存在:自動(dòng)創(chuàng)建該表,用于記錄遷移歷史
- 已存在:讀取已有遷移記錄
千萬(wàn)不要手動(dòng)的修改歷史表的任何數(shù)據(jù),不然肯定會(huì)導(dǎo)致版本管理錯(cuò)誤。
1.2、 遷移掃描
腳本加載
掃描配置的 locations 路徑(默認(rèn) classpath:db/migration),識(shí)別兩類腳本:
- 版本化遷移腳本(
V開頭) - 可重復(fù)遷移腳本(
R開頭)
1.3、校驗(yàn)階段
校驗(yàn) Checksum
對(duì)比已執(zhí)行腳本的 checksum 與本地文件的 checksum:
- 若已執(zhí)行腳本的 checksum 發(fā)生變化 → 拋出錯(cuò)誤(防止篡改歷史腳本)
- 校驗(yàn)通過(guò) → 進(jìn)入遷移階段
1.4、 遷移執(zhí)行
版本化遷移
按版本號(hào)順序執(zhí)行所有 未應(yīng)用 的 V 前綴腳本,且 僅執(zhí)行一次
可重復(fù)遷移
按文件名順序執(zhí)行 R 前綴腳本,當(dāng)腳本內(nèi)容變化時(shí) 重新執(zhí)行
1.5、 更新元數(shù)據(jù)
每個(gè)成功執(zhí)行的腳本會(huì)被記錄到 flyway_schema_history 表,包含:
版本號(hào)
腳本名稱
checksum
執(zhí)行時(shí)間
執(zhí)行狀態(tài)
如圖就是一個(gè)默認(rèn)的歷史表中數(shù)據(jù)。

在這里詳細(xì)解釋一個(gè)flyway中的兩種字母開頭的執(zhí)行腳本的不同;
V 開頭 vs R 開頭腳本的區(qū)別
1. 版本化遷移腳本(V 前綴)
命名規(guī)則V<Version>__<Description>.sql(例如 V1.2__Create_User_Table.sql)
Version:唯一且不可變的版本號(hào)(建議使用語(yǔ)義化版本,如1.0.1)Description:人類可讀的描述(使用下劃線分隔單詞)
核心特性
一次性執(zhí)行:每個(gè)腳本僅執(zhí)行一次
順序敏感:按版本號(hào)順序依次執(zhí)行
內(nèi)容不可變:已執(zhí)行的腳本內(nèi)容不可修改(否則校驗(yàn)失?。?/p>
典型場(chǎng)景
- 創(chuàng)建/修改表結(jié)構(gòu)
- 新增索引或約束
- 一次性數(shù)據(jù)遷移(如初始化基礎(chǔ)數(shù)據(jù))
2. 可重復(fù)遷移腳本(R 前綴)
命名規(guī)則R__<Description>.sql(例如 R__Update_Product_View.sql)
- 沒有版本號(hào)
Description:描述腳本作用(按字母順序排序執(zhí)行)
核心特性
- 重復(fù)執(zhí)行:腳本內(nèi)容變化時(shí)自動(dòng)重新執(zhí)行
- 順序依賴:按文件名字母順序執(zhí)行
- 內(nèi)容可變:允許修改后重新應(yīng)用
典型場(chǎng)景
- 維護(hù)視圖(View)或存儲(chǔ)過(guò)程(Stored Procedure)
- 更新靜態(tài)數(shù)據(jù)(如多環(huán)境差異化配置)
- 重建索引或物化視圖
關(guān)鍵對(duì)比總結(jié)
| 特性 | V 前綴腳本 | R 前綴腳本 |
|---|---|---|
| 執(zhí)行次數(shù) | 僅一次 | 內(nèi)容變化時(shí)重復(fù)執(zhí)行 |
| 版本號(hào) | 必須唯一且遞增 | 無(wú)版本號(hào) |
| 內(nèi)容修改 | 禁止修改(會(huì)導(dǎo)致校驗(yàn)失敗) | 允許修改(觸發(fā)重新執(zhí)行) |
| 執(zhí)行順序 | 按版本號(hào)順序 | 按文件名字母順序 |
| 適用場(chǎng)景 | 結(jié)構(gòu)變更、一次性操作 | 可重復(fù)邏輯、數(shù)據(jù)維護(hù) |
最佳實(shí)踐建議
版本化腳本 (V)
- 使用語(yǔ)義化版本(如
V1.2.3) - 每個(gè)腳本完成一個(gè)獨(dú)立的變更任務(wù)
- 禁止修改已提交到代碼倉(cāng)庫(kù)的
V腳本
可重復(fù)腳本 (R)
- 用于維護(hù)視圖、存儲(chǔ)過(guò)程等易變對(duì)象
- 通過(guò)文件名控制執(zhí)行順序(如
R__01_ViewA.sql,R__02_ViewB.sql) - 謹(jǐn)慎修改生產(chǎn)環(huán)境的
R腳本(可能觸發(fā)全量更新)
混合使用策略
- 用
V腳本管理表結(jié)構(gòu)變更 - 用
R腳本管理視圖和存儲(chǔ)過(guò)程
示例:
db/migration/ ├── V1.0__Create_Tables.sql ├── V1.1__Add_Indexes.sql └── R__Update_Views.sql
校驗(yàn)保護(hù)
- 生產(chǎn)環(huán)境務(wù)必啟用
validate-on-migrate: true - 開發(fā)環(huán)境可開啟
flyway.validate-migration-naming: true強(qiáng)制命名校驗(yàn)
通過(guò)合理使用 V 和 R 腳本,可以實(shí)現(xiàn)數(shù)據(jù)庫(kù)變更的 原子性 和 可追溯性,同時(shí)適應(yīng)不同場(chǎng)景的靈活性需求。
2、使用spring boot項(xiàng)目整合flyway
2.1、新創(chuàng)建一個(gè)spring boot項(xiàng)目,并導(dǎo)入一些初始的依賴;
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<!-- 無(wú)需指定版本(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>
<!-- 無(wú)需指定版本(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>需要注意的一點(diǎn)是,spring官方自動(dòng)管理的flyway的版本,所以我們只需要指定spring的版本就自動(dòng)會(huì)兼容合適的flyway版本,我的spring boot版本為3.3.9
我們主要使用到的依賴有三個(gè):
flyway-core:flyway的核心依賴
flyway-mysql:指定數(shù)據(jù)庫(kù)的類型
mybatis-spring-boot-starter: 數(shù)據(jù)源的自動(dòng)配置,也可以是其他的依賴坐標(biāo)。不一定要是mybatis,如JDBC、JPA等都可以
2.2、配置相應(yīng)的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"] # 修正為數(shù)組格式
table: flyway_schema_history
baseline-on-migrate: true # 必須啟用(處理已有表場(chǎng)景)
sql-migration-prefix: "V"
sql-migration-separator: "__"
sql-migration-suffixes: [".sql"] # 數(shù)組格式
logging:
level:
org.flywaydb: TRACE # 輸出最詳細(xì)日志我們只需要配置一些flyway的屬性,就可以直接使用flyway了。
2.3、編寫相應(yīng)的sql執(zhí)行語(yǔ)句,并且存放在固定的文件地址
-- 創(chuàng)建用戶表
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
);
-- 初始數(shù)據(jù)插入
INSERT INTO user (username, email) VALUES
('admin', 'admin@example.com'),
('user1', 'user1@example.com');我這里就創(chuàng)建了一張數(shù)據(jù)表,并且插入了一些數(shù)據(jù);
將SQL腳本放在合適的位置:

注意SQL腳本的存放位置不是亂放的,要符合我們之前在yml配置文件中書寫的配置,SQL腳本的名稱也不是隨便取得,要符合flyway的命名規(guī)范。
2.4、運(yùn)行spring boot項(xiàng)目
我們配置好了這些之后,就可以直接啟動(dòng)spring boot項(xiàng)目了。如果你是第一次啟動(dòng)項(xiàng)目,flyway會(huì)自動(dòng)掃描相應(yīng)文件夾下的SQL腳本,并在你的數(shù)據(jù)庫(kù)中建立一個(gè)歷史記錄表 flyway_schema_history。要特別注意的是我們千萬(wàn)不要手動(dòng)的修改這張表中的任何數(shù)據(jù),flyway就是根據(jù)這張歷史記錄表來(lái)進(jìn)行SQL腳本的執(zhí)行等等一系列操作。

我們可以直接在控制臺(tái)中看到flyway已經(jīng)順利的執(zhí)行我們相應(yīng)的SQL腳本
我們現(xiàn)在可以連接一下數(shù)據(jù)庫(kù)來(lái)看看是否正確

可以看到數(shù)據(jù)庫(kù)中已經(jīng)有了相應(yīng)的數(shù)據(jù)表,并且數(shù)據(jù)表中已經(jīng)有了一些初始數(shù)據(jù)了
這個(gè)是我們第一次啟動(dòng)spring boot項(xiàng)目時(shí)自動(dòng)執(zhí)行的SQL腳本。那么等我們第二次啟動(dòng)時(shí),flyway還是會(huì)掃描相應(yīng)的SQL腳本,同時(shí)查詢 flyway_schema_history 歷史表,來(lái)判斷SQL腳本要不要執(zhí)行。當(dāng)我們?cè)诖诉\(yùn)行spring boot項(xiàng)目:

我們?cè)诳刂婆_(tái)的日志中可以很清楚的看到flyway的執(zhí)行過(guò)程。
3、總結(jié)
以上,就是我們使用spring boot整合flyway來(lái)進(jìn)行數(shù)據(jù)庫(kù)的版本管理??傮w來(lái)說(shuō)是非常簡(jiǎn)單的,我們只需要一些簡(jiǎn)單的配置和遵守一些flyway的命名規(guī)定就可以直接使用flyway了。這也是spring官方一直在努力推行的
約定大于配置,配置大于編碼
當(dāng)然,flyway的功能還有很多,這篇文章也只是初步幫你認(rèn)識(shí)一下flyway。并且使用spring boot來(lái)簡(jiǎn)單的使用flyway的基本功能,但總的來(lái)說(shuō),我們幾乎可以只通過(guò)一些配置文件中屬性來(lái)使用flyway的絕大部分功能,一下我整理了一些常用的flyway屬性,供大家參考:
spring:
flyway:
# 基礎(chǔ)配置
enabled: true # 是否啟用 Flyway,默認(rèn) true
url: jdbc:mysql://localhost:3306/db # 覆蓋默認(rèn)數(shù)據(jù)庫(kù)連接(可選)
user: root # 覆蓋默認(rèn)數(shù)據(jù)庫(kù)用戶(可選)
password: root # 覆蓋默認(rèn)數(shù)據(jù)庫(kù)密碼(可選)
# 腳本管理
locations: # 遷移腳本路徑(默認(rèn) classpath:db/migration)
- classpath:db/migrations
- filesystem:/opt/migrations
encoding: UTF-8 # 腳本文件編碼,默認(rèn) UTF-8
sql-migration-prefix: V # 版本遷移腳本前綴,默認(rèn) "V"
repeatable-sql-migration-prefix: R # 可重復(fù)遷移腳本前綴,默認(rèn) "R"
sql-migration-separator: __ # 腳本名稱分隔符,默認(rèn)雙下劃線
sql-migration-suffixes: # 腳本后綴列表,默認(rèn) [".sql"]
- .sql
- .pgsql
# 遷移規(guī)則
schemas: public # Flyway 管理的 schema 列表(逗號(hào)分隔)
table: flyway_history # 元數(shù)據(jù)表名,默認(rèn) "flyway_schema_history"
baseline-on-migrate: false # 遷移時(shí)自動(dòng)執(zhí)行基線(默認(rèn) false)
baseline-version: 1 # 基線版本號(hào),默認(rèn) "1"
baseline-description: Initial Setup # 基線描述
target: latest # 目標(biāo)版本(默認(rèn)最新版本,可用版本號(hào)如 "3.1")
out-of-order: false # 是否允許亂序執(zhí)行遷移(默認(rèn) false)
validate-on-migrate: true # 遷移時(shí)校驗(yàn)?zāi)_本(默認(rèn) true)
ignore-missing-migrations: false # 忽略缺失的遷移記錄(默認(rèn) false)
# 占位符配置
placeholder-replacement: true # 啟用占位符替換(默認(rèn) true)
placeholders: # 自定義占位符鍵值對(duì)
key1: value1
key2: value2
# 高級(jí)配置
clean-on-validation-error: false # 校驗(yàn)失敗時(shí)自動(dòng)執(zhí)行 clean(危險(xiǎn)!默認(rèn) false)
connect-retries: 3 # 連接失敗重試次數(shù)(默認(rèn) 0)
lock-retry-count: 50 # 獲取鎖的重試次數(shù)(默認(rèn) 50)
group: false # 將相同版本的遷移合并為單個(gè)事務(wù)(默認(rèn) false)
mixed: false # 是否允許混合 DDL 和 DML(默認(rèn) false)
skip-default-callbacks: false # 跳過(guò)默認(rèn)回調(diào)(默認(rèn) false)
skip-default-resolvers: false # 跳過(guò)默認(rèn)解析器(默認(rèn) false)
init-sqls: # 獲取連接后立即執(zhí)行的 SQL 語(yǔ)句
- SET ROLE 'myuser'
# 多環(huán)境配置示例
---
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"
關(guān)鍵配置說(shuō)明:
基礎(chǔ)配置:默認(rèn)會(huì)復(fù)用 spring.datasource 配置,需要覆蓋時(shí)單獨(dú)指定
腳本管理:通過(guò)前綴/后綴/路徑控制腳本識(shí)別規(guī)則
遷移規(guī)則:控制基線、校驗(yàn)、執(zhí)行順序等核心行為
生產(chǎn)環(huán)境注意事項(xiàng):
clean-on-validation-error應(yīng)始終保持falseout-of-order需謹(jǐn)慎啟用- 建議明確指定
target版本控制生產(chǎn)環(huán)境遷移
最佳實(shí)踐:
- 使用 classpath 和 filesystem 組合路徑管理腳本
- 通過(guò) placeholders 實(shí)現(xiàn)環(huán)境差異化配置
- 啟用校驗(yàn)確保遷移安全
可以通過(guò) flyway.validateMigrationNaming 配置項(xiàng)(默認(rèn) false)開啟嚴(yán)格的腳本命名校驗(yàn),建議開發(fā)環(huán)境開啟。
flyway的官網(wǎng)地址為:https://flywaydb.org/
你有如果想了解更多有關(guān)flyway的信息,可以直接訪問官網(wǎng)
到此這篇關(guān)于spring boot整合flyway實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)維護(hù)的示例代碼的文章就介紹到這了,更多相關(guān)springboot flyway數(shù)據(jù)動(dòng)態(tài)維護(hù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Flyway的方法(數(shù)據(jù)庫(kù)版本遷移工具)
- Flyway詳解及Springboot集成Flyway的詳細(xì)教程
- SpringBoot整合flyway實(shí)現(xiàn)步驟解析
- SpringBoot使用flyway初始化數(shù)據(jù)庫(kù)
- SpringBoot整合flyway實(shí)現(xiàn)自動(dòng)創(chuàng)建表的方法
- SpringBoot項(xiàng)目集成Flyway詳細(xì)過(guò)程
- SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫(kù)管理的操作方法
- SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn)示例
- springboot配置flyway(入門級(jí)別教程)
相關(guān)文章
SpringBoot中注解實(shí)現(xiàn)定時(shí)任務(wù)的兩種方式
這篇文章主要介紹了SpringBoot中注解實(shí)現(xiàn)定時(shí)任務(wù)的兩種方式,SpringBoot 定時(shí)任務(wù)是一種在SpringBoot應(yīng)用中自動(dòng)執(zhí)行任務(wù)的機(jī)制,通過(guò)使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時(shí)任務(wù),需要的朋友可以參考下2023-10-10
springboot定時(shí)任務(wù)@Scheduled執(zhí)行多次的問題
這篇文章主要介紹了springboot定時(shí)任務(wù)@Scheduled執(zhí)行多次問題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作
這篇文章主要介紹了Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
SSM項(xiàng)目中使用攔截器和過(guò)濾器的實(shí)現(xiàn)示例
這篇文章主要介紹了SSM項(xiàng)目中使用攔截器和過(guò)濾器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Mybatis關(guān)聯(lián)查詢遇到的坑-無(wú)主鍵的關(guān)聯(lián)數(shù)據(jù)去重問題
這篇文章主要介紹了Mybatis關(guān)聯(lián)查詢遇到的坑-無(wú)主鍵的關(guān)聯(lián)數(shù)據(jù)去重問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Idea Project文件目錄不見了,只剩External Libraries和imi文件的解決
這篇文章主要介紹了Idea Project文件目錄不見了,只剩External Libraries和imi文件的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

