springboot集成flyway全過程
springboot:集成flyway
一、簡介
? Flyway是一款開源的數(shù)據(jù)庫版本管理工具,他可以很方便的在命令行中使用,或者在java應(yīng)用程序中引入,用于管理我們的數(shù)據(jù)庫版本。
? Flyway是一款數(shù)據(jù)庫遷移(migration)工具。簡單點說,就是在你部署應(yīng)用的時候,幫你執(zhí)行數(shù)據(jù)庫腳本的工具。Flyway支持SQL和Java兩種類型的腳本,你可以將腳本打包到應(yīng)用程序中,在應(yīng)用程序啟動時,由Flyway來管理這些腳本的執(zhí)行,這些腳本被Flyway稱之為migration
二、Flyway工作流程
項目啟動,應(yīng)用程序完成數(shù)據(jù)庫連接池的建立之后,F(xiàn)lyway自動運(yùn)行
初次使用時,F(xiàn)lyway會創(chuàng)建一個flyway_schema_history 表,用于記錄sql執(zhí)行記錄
Flyway會掃描項目指定路徑下(默認(rèn)是 classpath:db/migration )的所有sql腳本,與 flyway_schema_history 表腳本記錄進(jìn)行比對。如果數(shù)據(jù)庫記錄執(zhí)行過的腳本記錄,與項目中的sql腳本不一致,F(xiàn)lyway會報錯并停止項目執(zhí)行
如果校驗通過,則根據(jù)表中的sql記錄最大版本號,忽略所有版本號不大于該版本的腳本。再按照版本號從小到大,逐個執(zhí)行其余腳本
三、配置文件使用Flyway
添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.4</version>
</dependency>添加相關(guān)配置
spring:
# 數(shù)據(jù)庫連接配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/flyway-demo?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
flyway:
# 是否啟用flyway
enabled: true
# 編碼格式,默認(rèn)UTF-8
encoding: UTF-8
# 遷移sql腳本文件存放路徑,默認(rèn)db/migration
locations: classpath:db/migration
# 遷移sql腳本文件名稱的前綴,默認(rèn)V
sql-migration-prefix: V
# 遷移sql腳本文件名稱的分隔符,默認(rèn)2個下劃線__
sql-migration-separator: __
# 遷移sql腳本文件名稱的后綴
sql-migration-suffixes: .sql
# 執(zhí)行遷移時是否自動調(diào)用驗證 當(dāng)你的 版本不符合邏輯 比如 你先執(zhí)行了 DML 而沒有 對應(yīng)的DDL 會拋出異常
validate-on-migrate: true
# 如果沒有 flyway_schema_history 這個 metadata 表, 在執(zhí)行 flyway migrate 命令之前, 必須先執(zhí)行 flyway baseline 命令
# 設(shè)置為 true 后 flyway 將在需要 baseline 的時候, 自動執(zhí)行一次 baseline
baseline-on-migrate: true
# metadata 版本控制信息表 默認(rèn) flyway_schema_history
table: flyway_schema_history
# 指定 baseline 的版本號,默認(rèn)值為 1, 低于該版本號的 SQL 文件, migrate 時會被忽略
baseline-version: 1創(chuàng)建腳本所在文件夾
根據(jù)上面配置文件中的腳本存放路徑,我們需要在resource目錄下建立文件夾 db/migration
sql腳本命名規(guī)范
對于Flyway,對數(shù)據(jù)庫的所有更改都稱為變遷(migrations)
- 版本變遷(Versioned Migrations): 每個版本執(zhí)行一次,包含有版本、描述和校驗和;常用于創(chuàng)建,修改,刪除表;插入,修改數(shù)據(jù)等
- 撤銷變遷(Undo Migrations): 版本變遷(Versioned Migrations)的反操作
- 可重復(fù)變遷(Repeatable Migrations): 可以執(zhí)行多次,包含描述和校驗和(沒有版本);主要用于視圖,存儲過程,函數(shù)等

- 前綴: V 代表版本變遷(Versioned Migrations), U 代表撤銷變遷(Undo Migrations), R 代表可重復(fù)變遷(Repeatable Migrations)
- 版本號: 唯一的版本號,比如V1.0.1
- 分隔符: __ (兩個下劃線)
- 描述信息: 描述信息
- 后綴: .sql
sql的執(zhí)行順序:
Flyway是采用了采用左對齊原則, 缺位用 0 代替,根據(jù)版本好來判斷那個sql先執(zhí)行
1.0.1.1 比 1.0.1 版本高。 1.0.10 比 1.0.9.4 版本高。 1.0.10 和 1.0.010 版本號一樣高, 每個版本號部分的前導(dǎo) 0 會被忽略
僅需要被執(zhí)行一次的SQL命名以大寫的"V"開頭,V+版本號(版本號的數(shù)字間以”.“或”_“分隔開)+雙下劃線(用來分隔版本號和描述)+文件描述+后綴名。
例如: V20201100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql
可重復(fù)運(yùn)行的SQL,則以大寫的“R”開頭,后面再以兩個下劃線分割,其后跟文件名稱,最后以.sql結(jié)尾。(不推薦使用)比如:R__truncate_user_dml.sql
其中,V開頭的SQL執(zhí)行優(yōu)先級要比R開頭的SQL優(yōu)先級高
啟動測試
三個文件如下:
- V1__create_user.sql
CREATE TABLE IF NOT EXISTS `user`
(
`USER_ID` INT NOT NULL AUTO_INCREMENT,
`USER_NAME` VARCHAR(100) NOT NULL COMMENT '用戶姓名',
`AGE` INT NOT NULL COMMENT '年齡',
`CREATED_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`CREATED_BY` varchar(100) NOT NULL DEFAULT 'UNKNOWN',
`UPDATED_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UPDATED_BY` varchar(100) NOT NULL DEFAULT 'UNKNOWN',
PRIMARY KEY (`USER_ID`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;- V2__add_user.sql
insert into `user`(user_name,age) values('lisi',33);- V3__add_user.sql
insert into `user`(user_name,age) values('lisi2222',33);- R__add_unknown_user.sql
insert into `user`(user_name,age) values('unknown',33);
查看mysql中Flyway的版本控制信息表


這里我們修改V3__add_user.sql文件他就會出現(xiàn)錯誤
[ERROR] Migration checksum mismatch for migration version 2
如果我們修改R__add_unknown_user.sql然后再次執(zhí)行,該腳本會再次執(zhí)行,并且flyway的歷史記錄表中也會增加本次執(zhí)行的記錄
四、Flyway配置清單
flyway.baseline-description對執(zhí)行遷移時基準(zhǔn)版本的描述.
flyway.baseline-on-migrate當(dāng)遷移時發(fā)現(xiàn)目標(biāo)schema非空,而且?guī)в袥]有元數(shù)據(jù)的表時,是否自動執(zhí)行基準(zhǔn)遷移,默認(rèn)false.
flyway.baseline-version開始執(zhí)行基準(zhǔn)遷移時對現(xiàn)有的schema的版本打標(biāo)簽,默認(rèn)值為1.
flyway.check-location檢查遷移腳本的位置是否存在,默認(rèn)false.
flyway.clean-on-validation-error當(dāng)發(fā)現(xiàn)校驗錯誤時是否自動調(diào)用clean,默認(rèn)false.
flyway.enabled是否開啟flywary,默認(rèn)true.
flyway.encoding設(shè)置遷移時的編碼,默認(rèn)UTF-8.
flyway.ignore-failed-future-migration當(dāng)讀取元數(shù)據(jù)表時是否忽略錯誤的遷移,默認(rèn)false.
flyway.init-sqls當(dāng)初始化好連接時要執(zhí)行的SQL.
flyway.locations遷移腳本的位置,默認(rèn)db/migration.
flyway.out-of-order是否允許無序的遷移,默認(rèn)false.
flyway.password目標(biāo)數(shù)據(jù)庫的密碼.
flyway.placeholder-prefix設(shè)置每個placeholder的前綴,默認(rèn)${.
flyway.placeholder-replacementplaceholders是否要被替換,默認(rèn)true.
flyway.placeholder-suffix設(shè)置每個placeholder的后綴,默認(rèn)}.
flyway.placeholders.[placeholder name]設(shè)置placeholder的value
flyway.schemas設(shè)定需要flywary遷移的schema,大小寫敏感,默認(rèn)為連接默認(rèn)的schema.
flyway.sql-migration-prefix遷移文件的前綴,默認(rèn)為V.
flyway.sql-migration-separator遷移腳本的文件名分隔符,默認(rèn)__
flyway.sql-migration-suffix遷移腳本的后綴,默認(rèn)為.sql
flyway.tableflyway使用的元數(shù)據(jù)表名,默認(rèn)為schema_version
flyway.target遷移時使用的目標(biāo)版本,默認(rèn)為latest version
flyway.url遷移時使用的JDBC URL,如果沒有指定的話,將使用配置的主數(shù)據(jù)源
flyway.user遷移數(shù)據(jù)庫的用戶名
flyway.validate-on-migrate遷移時是否校驗,默認(rèn)為true五、maven插件的使用
上面的操作,每次我們想要migration都需要運(yùn)行整個springboot項目,并且只能執(zhí)行migrate一種命令,其實flyway還是有很多其它命令的,maven插件給了我們不需要啟動項目就能執(zhí)行flyway各種命令的機(jī)會。
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>5.2.4</version>
<configuration>
<url>jdbc:mysql://localhost:3306/flyway-demo?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
</url>
<user>root</user>
<password>root</password>
<driver>com.mysql.jdbc.Driver</driver>
</configuration>
</plugin>
</plugins>
</build>
migrate
Migrate是指把數(shù)據(jù)庫Schema遷移到最新版本,是Flyway工作流的核心功能,F(xiàn)lyway在Migrate時會檢查Metadata(元數(shù)據(jù))表,如果不存在會創(chuàng)建Metadata表,Metadata表主要用于記錄版本變更歷史以及Checksum之類的
baseline
Baseline針對已經(jīng)存在Schema結(jié)構(gòu)的數(shù)據(jù)庫的一種解決方案,即實現(xiàn)在非空數(shù)據(jù)庫中新建Metadata表,并把Migrations應(yīng)用到該數(shù)據(jù)庫。
Baseline可以應(yīng)用到特定的版本,這樣在已有表結(jié)構(gòu)的數(shù)據(jù)庫中也可以實現(xiàn)添加Metadata表,從而利用Flyway進(jìn)行新Migrations的管理了
clean(慎用)
Clean相對比較容易理解,清除掉對應(yīng)數(shù)據(jù)庫Schema中所有的對象,包括表結(jié)構(gòu),視圖,存儲過程等,clean操作在dev 和 test階段很好用,但在生產(chǎn)環(huán)境務(wù)必禁用
info
Info用于打印所有Migrations的詳細(xì)和狀態(tài)信息,其實也是通過Metadata表和Migrations完成的,Info能夠幫助快速定位當(dāng)前的數(shù)據(jù)庫版本,以及查看執(zhí)行成功和失敗的Migrations。下圖很好地示意了Info打印出來的信息
repair
repair操作能夠修復(fù)Metadata表,該操作在Metadata表出現(xiàn)錯誤時是非常有用的
validate
Validate是指驗證已經(jīng)Apply的Migrations是否有變更,F(xiàn)lyway是默認(rèn)是開啟驗證的。
Validate原理是對比Metadata表與本地Migrations的Checksum值,如果值相同則驗證通過,否則驗證失敗,從而可以防止對已經(jīng)Apply到數(shù)據(jù)庫的本地Migrations的無意修改
undo
撤銷操作,社區(qū)版不支持
六、flyway知識補(bǔ)充
- flyway執(zhí)行migrate必須在空白的數(shù)據(jù)庫上進(jìn)行,否則報錯
- 對于已經(jīng)有數(shù)據(jù)的數(shù)據(jù)庫,必須先baseline,然后才能migrate
- clean操作是刪除數(shù)據(jù)庫的所有內(nèi)容,包括baseline之前的內(nèi)容
- 盡量不要修改已經(jīng)執(zhí)行過的SQL,即便是R開頭的可反復(fù)執(zhí)行的SQL,它們會不利于數(shù)據(jù)遷移
- 當(dāng)需要做數(shù)據(jù)遷移的時候,更換一個新的空白數(shù)據(jù)庫,執(zhí)行下migrate命令,所有的數(shù)據(jù)庫更改都可以一步到位地遷移過去
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java 數(shù)據(jù)結(jié)構(gòu)基本算法希爾排序
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)基本算法希爾排序的相關(guān)資料,需要的朋友可以參考下2017-08-08
Spring Schedule Task動態(tài)改寫Cron配置方式
這篇文章主要介紹了Spring Schedule Task動態(tài)改寫Cron配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
JavaWeb實現(xiàn)用戶登錄注冊功能實例代碼(基于Servlet+JSP+JavaBean模式)
這篇文章主要基于Servlet+JSP+JavaBean開發(fā)模式實現(xiàn)JavaWeb用戶登錄注冊功能實例代碼,非常實用,本文介紹的非常詳細(xì),具有參考借鑒價值,感興趣的朋友一起看看吧2016-05-05
Java實現(xiàn)的數(shù)字簽名算法RSA完整示例
這篇文章主要介紹了Java實現(xiàn)的數(shù)字簽名算法RSA,結(jié)合完整實例形式詳細(xì)分析了RSA算法的相關(guān)概念、原理、實現(xiàn)方法及操作技巧,需要的朋友可以參考下2019-09-09
Spring中@Autowired @Resource @Inject三個注解有什么區(qū)別
在我們使用Spring框架進(jìn)行日常開發(fā)過程中,經(jīng)常會使用@Autowired, @Resource, @Inject注解來進(jìn)行依賴注入,下面來介紹一下這三個注解有什么區(qū)別2023-03-03
springboot+logback的多環(huán)境配置全過程
文章介紹了Spring Boot多環(huán)境配置的兩種方式:推薦使用bootstrap.yml+環(huán)境專用文件(如bootstrap-dev.yml)區(qū)分配置,而舊版(2.6.x以下)可采用bootstrap.yml+application-xxx.yml,同時說明Logback需將配置文件改為logback-spring.xml以支持springProperty多環(huán)境日志設(shè)置2025-09-09

