spring boot整合flyway實現(xiàn)數(shù)據(jù)的動態(tài)維護(hù)的示例代碼
1、簡單介紹一下flyway
Flyway 是一款開源的數(shù)據(jù)庫版本控制工具,主要用于管理數(shù)據(jù)庫結(jié)構(gòu)的變更(如創(chuàng)建表、修改字段、插入數(shù)據(jù)等)。它通過跟蹤和執(zhí)行版本化的遷移腳本,幫助團(tuán)隊實現(xiàn)數(shù)據(jù)庫變更的自動化。接下來簡單介紹一下flyway的工作流程:
1.1、 初始化階段
檢查元數(shù)據(jù)表
Flyway 首先檢查目標(biāo)數(shù)據(jù)庫中是否存在 flyway_schema_history
表(默認(rèn)表名稱,也可以自定義歷史表名稱)。
- 不存在:自動創(chuàng)建該表,用于記錄遷移歷史
- 已存在:讀取已有遷移記錄
千萬不要手動的修改歷史表的任何數(shù)據(jù),不然肯定會導(dǎo)致版本管理錯誤。
1.2、 遷移掃描
腳本加載
掃描配置的 locations
路徑(默認(rèn) classpath:db/migration
),識別兩類腳本:
- 版本化遷移腳本(
V
開頭) - 可重復(fù)遷移腳本(
R
開頭)
1.3、校驗階段
校驗 Checksum
對比已執(zhí)行腳本的 checksum
與本地文件的 checksum
:
- 若已執(zhí)行腳本的 checksum 發(fā)生變化 → 拋出錯誤(防止篡改歷史腳本)
- 校驗通過 → 進(jìn)入遷移階段
1.4、 遷移執(zhí)行
版本化遷移
按版本號順序執(zhí)行所有 未應(yīng)用 的 V
前綴腳本,且 僅執(zhí)行一次
可重復(fù)遷移
按文件名順序執(zhí)行 R
前綴腳本,當(dāng)腳本內(nèi)容變化時 重新執(zhí)行
1.5、 更新元數(shù)據(jù)
每個成功執(zhí)行的腳本會被記錄到 flyway_schema_history
表,包含:
版本號
腳本名稱
checksum
執(zhí)行時間
執(zhí)行狀態(tài)
如圖就是一個默認(rèn)的歷史表中數(shù)據(jù)。
在這里詳細(xì)解釋一個flyway中的兩種字母開頭的執(zhí)行腳本的不同;
V
開頭 vs R
開頭腳本的區(qū)別
1. 版本化遷移腳本(V
前綴)
命名規(guī)則V<Version>__<Description>.sql
(例如 V1.2__Create_User_Table.sql
)
Version
:唯一且不可變的版本號(建議使用語義化版本,如1.0.1
)Description
:人類可讀的描述(使用下劃線分隔單詞)
核心特性
一次性執(zhí)行:每個腳本僅執(zhí)行一次
順序敏感:按版本號順序依次執(zhí)行
內(nèi)容不可變:已執(zhí)行的腳本內(nèi)容不可修改(否則校驗失敗)
典型場景
- 創(chuàng)建/修改表結(jié)構(gòu)
- 新增索引或約束
- 一次性數(shù)據(jù)遷移(如初始化基礎(chǔ)數(shù)據(jù))
2. 可重復(fù)遷移腳本(R
前綴)
命名規(guī)則R__<Description>.sql
(例如 R__Update_Product_View.sql
)
- 沒有版本號
Description
:描述腳本作用(按字母順序排序執(zhí)行)
核心特性
- 重復(fù)執(zhí)行:腳本內(nèi)容變化時自動重新執(zhí)行
- 順序依賴:按文件名字母順序執(zhí)行
- 內(nèi)容可變:允許修改后重新應(yīng)用
典型場景
- 維護(hù)視圖(View)或存儲過程(Stored Procedure)
- 更新靜態(tài)數(shù)據(jù)(如多環(huán)境差異化配置)
- 重建索引或物化視圖
關(guān)鍵對比總結(jié)
特性 | V 前綴腳本 | R 前綴腳本 |
---|---|---|
執(zhí)行次數(shù) | 僅一次 | 內(nèi)容變化時重復(fù)執(zhí)行 |
版本號 | 必須唯一且遞增 | 無版本號 |
內(nèi)容修改 | 禁止修改(會導(dǎo)致校驗失?。?/td> | 允許修改(觸發(fā)重新執(zhí)行) |
執(zhí)行順序 | 按版本號順序 | 按文件名字母順序 |
適用場景 | 結(jié)構(gòu)變更、一次性操作 | 可重復(fù)邏輯、數(shù)據(jù)維護(hù) |
最佳實踐建議
版本化腳本 (V)
- 使用語義化版本(如
V1.2.3
) - 每個腳本完成一個獨(dú)立的變更任務(wù)
- 禁止修改已提交到代碼倉庫的
V
腳本
可重復(fù)腳本 (R)
- 用于維護(hù)視圖、存儲過程等易變對象
- 通過文件名控制執(zhí)行順序(如
R__01_ViewA.sql
,R__02_ViewB.sql
) - 謹(jǐn)慎修改生產(chǎn)環(huán)境的
R
腳本(可能觸發(fā)全量更新)
混合使用策略
- 用
V
腳本管理表結(jié)構(gòu)變更 - 用
R
腳本管理視圖和存儲過程
示例:
db/migration/ ├── V1.0__Create_Tables.sql ├── V1.1__Add_Indexes.sql └── R__Update_Views.sql
校驗保護(hù)
- 生產(chǎn)環(huán)境務(wù)必啟用
validate-on-migrate: true
- 開發(fā)環(huán)境可開啟
flyway.validate-migration-naming: true
強(qiáng)制命名校驗
通過合理使用 V
和 R
腳本,可以實現(xiàn)數(shù)據(jù)庫變更的 原子性 和 可追溯性,同時適應(yīng)不同場景的靈活性需求。
2、使用spring boot項目整合flyway
2.1、新創(chuàng)建一個spring boot項目,并導(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> <!-- 無需指定版本(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>
需要注意的一點(diǎn)是,spring官方自動管理的flyway的版本,所以我們只需要指定spring的版本就自動會兼容合適的flyway版本,我的spring boot版本為3.3.9
我們主要使用到的依賴有三個:
flyway-core:flyway的核心依賴
flyway-mysql:指定數(shù)據(jù)庫的類型
mybatis-spring-boot-starter: 數(shù)據(jù)源的自動配置,也可以是其他的依賴坐標(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 # 必須啟用(處理已有表場景) 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í)行語句,并且存放在固定的文件地址
-- 創(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項目
我們配置好了這些之后,就可以直接啟動spring boot項目了。如果你是第一次啟動項目,flyway會自動掃描相應(yīng)文件夾下的SQL腳本,并在你的數(shù)據(jù)庫中建立一個歷史記錄表 flyway_schema_history。要特別注意的是我們千萬不要手動的修改這張表中的任何數(shù)據(jù),flyway就是根據(jù)這張歷史記錄表來進(jìn)行SQL腳本的執(zhí)行等等一系列操作。
我們可以直接在控制臺中看到flyway已經(jīng)順利的執(zhí)行我們相應(yīng)的SQL腳本
我們現(xiàn)在可以連接一下數(shù)據(jù)庫來看看是否正確
可以看到數(shù)據(jù)庫中已經(jīng)有了相應(yīng)的數(shù)據(jù)表,并且數(shù)據(jù)表中已經(jīng)有了一些初始數(shù)據(jù)了
這個是我們第一次啟動spring boot項目時自動執(zhí)行的SQL腳本。那么等我們第二次啟動時,flyway還是會掃描相應(yīng)的SQL腳本,同時查詢 flyway_schema_history
歷史表,來判斷SQL腳本要不要執(zhí)行。當(dāng)我們在此運(yùn)行spring boot項目:
我們在控制臺的日志中可以很清楚的看到flyway的執(zhí)行過程。
3、總結(jié)
以上,就是我們使用spring boot整合flyway來進(jìn)行數(shù)據(jù)庫的版本管理??傮w來說是非常簡單的,我們只需要一些簡單的配置和遵守一些flyway的命名規(guī)定就可以直接使用flyway了。這也是spring官方一直在努力推行的
約定大于配置,配置大于編碼
當(dāng)然,flyway的功能還有很多,這篇文章也只是初步幫你認(rèn)識一下flyway。并且使用spring boot來簡單的使用flyway的基本功能,但總的來說,我們幾乎可以只通過一些配置文件中屬性來使用flyway的絕大部分功能,一下我整理了一些常用的flyway屬性,供大家參考:
spring: flyway: # 基礎(chǔ)配置 enabled: true # 是否啟用 Flyway,默認(rèn) true url: jdbc:mysql://localhost:3306/db # 覆蓋默認(rèn)數(shù)據(jù)庫連接(可選) user: root # 覆蓋默認(rèn)數(shù)據(jù)庫用戶(可選) password: root # 覆蓋默認(rèn)數(shù)據(jù)庫密碼(可選) # 腳本管理 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 列表(逗號分隔) table: flyway_history # 元數(shù)據(jù)表名,默認(rèn) "flyway_schema_history" baseline-on-migrate: false # 遷移時自動執(zhí)行基線(默認(rèn) false) baseline-version: 1 # 基線版本號,默認(rèn) "1" baseline-description: Initial Setup # 基線描述 target: latest # 目標(biāo)版本(默認(rèn)最新版本,可用版本號如 "3.1") out-of-order: false # 是否允許亂序執(zhí)行遷移(默認(rèn) false) validate-on-migrate: true # 遷移時校驗?zāi)_本(默認(rèn) true) ignore-missing-migrations: false # 忽略缺失的遷移記錄(默認(rèn) false) # 占位符配置 placeholder-replacement: true # 啟用占位符替換(默認(rèn) true) placeholders: # 自定義占位符鍵值對 key1: value1 key2: value2 # 高級配置 clean-on-validation-error: false # 校驗失敗時自動執(zhí)行 clean(危險!默認(rèn) false) connect-retries: 3 # 連接失敗重試次數(shù)(默認(rèn) 0) lock-retry-count: 50 # 獲取鎖的重試次數(shù)(默認(rèn) 50) group: false # 將相同版本的遷移合并為單個事務(wù)(默認(rèn) false) mixed: false # 是否允許混合 DDL 和 DML(默認(rèn) false) skip-default-callbacks: false # 跳過默認(rèn)回調(diào)(默認(rèn) false) skip-default-resolvers: false # 跳過默認(rèn)解析器(默認(rèn) false) init-sqls: # 獲取連接后立即執(zhí)行的 SQL 語句 - 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)鍵配置說明:
基礎(chǔ)配置:默認(rèn)會復(fù)用 spring.datasource
配置,需要覆蓋時單獨(dú)指定
腳本管理:通過前綴/后綴/路徑控制腳本識別規(guī)則
遷移規(guī)則:控制基線、校驗、執(zhí)行順序等核心行為
生產(chǎn)環(huán)境注意事項:
clean-on-validation-error
應(yīng)始終保持false
out-of-order
需謹(jǐn)慎啟用- 建議明確指定
target
版本控制生產(chǎn)環(huán)境遷移
最佳實踐:
- 使用 classpath 和 filesystem 組合路徑管理腳本
- 通過 placeholders 實現(xiàn)環(huán)境差異化配置
- 啟用校驗確保遷移安全
可以通過 flyway.validateMigrationNaming 配置項(默認(rèn) false)開啟嚴(yán)格的腳本命名校驗,建議開發(fā)環(huán)境開啟。
flyway的官網(wǎng)地址為:https://flywaydb.org/
你有如果想了解更多有關(guān)flyway的信息,可以直接訪問官網(wǎng)
到此這篇關(guān)于spring boot整合flyway實現(xiàn)數(shù)據(jù)的動態(tài)維護(hù)的示例代碼的文章就介紹到這了,更多相關(guān)springboot flyway數(shù)據(jù)動態(tài)維護(hù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Flyway的方法(數(shù)據(jù)庫版本遷移工具)
- Flyway詳解及Springboot集成Flyway的詳細(xì)教程
- SpringBoot整合flyway實現(xiàn)步驟解析
- SpringBoot使用flyway初始化數(shù)據(jù)庫
- SpringBoot整合flyway實現(xiàn)自動創(chuàng)建表的方法
- SpringBoot項目集成Flyway詳細(xì)過程
- SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫管理的操作方法
- SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫遷移的實現(xiàn)示例
- springboot配置flyway(入門級別教程)
相關(guān)文章
SpringBoot定時任務(wù)多線程實現(xiàn)示例
在真實的Java開發(fā)環(huán)境中,我們經(jīng)常會需要用到定時任務(wù)來幫助我們完成一些特殊的任務(wù),本文主要介紹了SpringBoot定時任務(wù)多線程實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12Java Spring 控制反轉(zhuǎn)(IOC)容器詳解
這篇文章主要為大家詳細(xì)介紹了Spring控制反轉(zhuǎn)IoC入門使用的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10Java子線程調(diào)用RequestContextHolder.getRequestAttributes()方法問題詳解
這篇文章主要介紹了Java子線程調(diào)用RequestContextHolder.getRequestAttributes()方法問題處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09Java組件commons fileupload實現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了Java組件commons fileupload實現(xiàn)文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10多模塊項目引入SpringSecurity后一直報404的解決方案
這篇文章主要介紹了多模塊項目引入SpringSecurity后一直報404的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06