從零搭建開發腳手架 Spring Boot集成Flyway實現數據庫版本管理
- Flyway是什么
- Flyway集成和使用
- 添加依賴
- 配置文件
- 腳本
- 測試
- 原理
- 高級
- 基于Java的遷移回調
Flyway是什么
Flyway是一款數據庫版本控制管理工具,支持數據庫版本自動升級。
- 項目初始化的時候,往往都是要先手動執行數據庫腳本。
- 在開發過程當中,數據結構或者數據有更新時,往往都要手動執行腳本同步開發環境、測試環境。
現在我們就可以使用flyway來幫我們自動的去完成這個工作。
Flyway集成和使用
添加依賴
- <dependency>
- <groupId>org.flywaydb</groupId>
- <artifactId>flyway-core</artifactId>
- </dependency>
由于是Spring Boot項目集成,版本直接使用默認的即可
配置文件
- spring:
- flyway:
- #是否開啟flyway,默認true
- enabled: true
- #當遷移時發現目標schema非空,而且沒有元數據的表時,(即迭代中項目)是否自動執行基準遷移,默認false.
- baseline-on-migrate: true
- # 是否允許無序運行遷移, 默認false,建議開發環境開啟,生成環境關閉
- out-of-order: true
- #設定SQL腳本的目錄,可以配置多個,比如為classpath:db/migration,filesystem:/sql-migrations,默認classpath:db/migration
- locations:
- - classpath:db/migration
更多參數見 https://flywaydb.org/documentation/configfiles
“這些參數配到springboot2 項目中, 需要加上 spring前綴
腳本
在resource目錄下面建立db.migration目錄,放置sql文件
sql腳本的格式:
- V/R+版本號+雙下劃線+描述+結束符:
- 例如:V20190429.1530__t_user_update.sql (開發環境:建議日期+時分秒)
- 例如:V1.1__init.sql(生產環境:建議把上面的腳步合并用版本號)
測試
默認情況下,Spring Boot在應用程序啟動時自動運行Flyway數據庫遷移。
結果如下:
注意:
Flyway社區版不支持MySQL5.7以下的版本了
https://flywaydb.org/documentation/database/mysql
原理
Flyway 需要在 DB 中先創建一個 metdata 表 (缺省表名為 flyway_schema_history), 在該表中保存著每次遷移的記錄, 記錄包含遷移腳本的版本號和 SQL 腳本的 checksum 值. 當一個新的 SQL 腳本被掃描到后, Flyway 解析該 SQL 腳本的版本號, 并和 metadata 表已執行的遷移對比, 如果該 SQL 腳本版本更新的話, 將在指定的 DB 上執行該 SQL 文件, 否則跳過該 SQL 文件.
兩個 flyway 版本號的比較, 采用左對齊原則, 缺位用 0 代替. 舉例如下:
- 1.2.9.4 比 1.2.9 版本高.
- 1.2.10 比 1.2.9.4 版本高.
- 1.2.10 和 1.2.010 版本號一樣高, 每個版本號部分的前導 0 會被忽略.
Flyway SQL 文件可以分為兩類:
- Versioned :用于版本升級, 每個版本有唯一的版本號并只能 apply 一次
- Repeatable :指可重復加載的 migration, 一旦 SQL 腳本的 checksum 有變動, flyway 就會重新應用該腳本. 它并不用于版本更新, 這類的 migration 總是在 versioned migration 執行之后才被執行
默認情況下, Migration SQL的命名規則如下圖:
img
其中的文件名由以下部分組成,除了使用默認配置外,某些部分還可自定義規則.
- prefix: 可配置,前綴標識,默認值 V 表示 Versioned, R 表示 Repeatable
- version: 標識版本號, 由一個或多個數字構成, 數字之間的分隔符可用點.或下劃線_
- separator: 可配置, 用于分隔版本標識與描述信息, 默認為兩個下劃線__
- description: 描述信息, 文字之間可以用下劃線或空格分隔
- suffix: 可配置, 后續標識, 默認為.sql*
Flyway 的 metadata 表結果如下:
- CREATE TABLE flyway_schema_history
- (
- installed_rank INT NOT NULL,
- version VARCHAR(50),
- description VARCHAR(200) NOT NULL,
- type VARCHAR(20) NOT NULL,
- script VARCHAR(1000) NOT NULL,
- checksum INT,
- installed_by VARCHAR(100) NOT NULL,
- installed_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- execution_time INT NOT NULL,
- success TINYINT(1) NOT NULL,
- PRIMARY KEY (installed_rank),
- INDEX flyway_schema_history_s_idx (success)
- )
- ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
高級
基于Java的遷移回調
Flyway使我們能夠使用兩種不同的方法(Java或SQL)創建回調。前者是最靈活的一種。它為我們提供了執行任意代碼的自由。
核心代碼如下:
- import lombok.extern.slf4j.Slf4j;
- import org.flywaydb.core.api.callback.BaseCallback;
- import org.flywaydb.core.api.callback.Context;
- import org.flywaydb.core.api.callback.Event;
- import org.flywaydb.core.internal.jdbc.JdbcTemplate;
- import org.springframework.context.annotation.Configuration;
- import java.sql.SQLException;
- @Configuration
- @Slf4j
- public class ExampleFlywayCallback extends BaseCallback {
- @Override
- public void handle(Event event, Context context) {
- switch (event) {
- // 在每次成功遷移后觸發。此事件將在與遷移相同的事務中觸發
- case AFTER_EACH_MIGRATE:
- log.info("{},", event);
- final JdbcTemplate jdbcTemplate = new JdbcTemplate(
- context.getConnection());
- // Create 10 random users
- for (int i = 1; i <= 10; i++) {
- try {
- jdbcTemplate.execute(String.format("insert into test_user"
- + " (username, first_name, last_name) values"
- + " ('%d@reflectoring.io', 'Elvis_%d', 'Presley_%d')", i, i, i));
- } catch (SQLException throwables) {
- throwables.printStackTrace();
- }
- }
- }
- }
- }
我們可以在Java遷移回調中執行所需的任何邏輯,可以靈活地實現更多變態需求。
參考:
https://www.cnblogs.com/harrychinese/p/springboot_flyway.html
https://blog.csdn.net/qq_38455201/article/details/103493041


























