springboot集成flyway全過(guò)程
springboot:集成flyway
一、簡(jiǎn)介
? Flyway是一款開(kāi)源的數(shù)據(jù)庫(kù)版本管理工具,他可以很方便的在命令行中使用,或者在java應(yīng)用程序中引入,用于管理我們的數(shù)據(jù)庫(kù)版本。
? Flyway是一款數(shù)據(jù)庫(kù)遷移(migration)工具。簡(jiǎn)單點(diǎn)說(shuō),就是在你部署應(yīng)用的時(shí)候,幫你執(zhí)行數(shù)據(jù)庫(kù)腳本的工具。Flyway支持SQL和Java兩種類型的腳本,你可以將腳本打包到應(yīng)用程序中,在應(yīng)用程序啟動(dòng)時(shí),由Flyway來(lái)管理這些腳本的執(zhí)行,這些腳本被Flyway稱之為migration
二、Flyway工作流程
項(xiàng)目啟動(dòng),應(yīng)用程序完成數(shù)據(jù)庫(kù)連接池的建立之后,F(xiàn)lyway自動(dòng)運(yùn)行
初次使用時(shí),F(xiàn)lyway會(huì)創(chuàng)建一個(gè)flyway_schema_history 表,用于記錄sql執(zhí)行記錄
Flyway會(huì)掃描項(xiàng)目指定路徑下(默認(rèn)是 classpath:db/migration )的所有sql腳本,與 flyway_schema_history 表腳本記錄進(jìn)行比對(duì)。如果數(shù)據(jù)庫(kù)記錄執(zhí)行過(guò)的腳本記錄,與項(xiàng)目中的sql腳本不一致,F(xiàn)lyway會(huì)報(bào)錯(cuò)并停止項(xiàng)目執(zhí)行
如果校驗(yàn)通過(guò),則根據(jù)表中的sql記錄最大版本號(hào),忽略所有版本號(hào)不大于該版本的腳本。再按照版本號(hào)從小到大,逐個(gè)執(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ù)庫(kù)連接配置 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個(gè)下劃線__ sql-migration-separator: __ # 遷移sql腳本文件名稱的后綴 sql-migration-suffixes: .sql # 執(zhí)行遷移時(shí)是否自動(dòng)調(diào)用驗(yàn)證 當(dāng)你的 版本不符合邏輯 比如 你先執(zhí)行了 DML 而沒(méi)有 對(duì)應(yīng)的DDL 會(huì)拋出異常 validate-on-migrate: true # 如果沒(méi)有 flyway_schema_history 這個(gè) metadata 表, 在執(zhí)行 flyway migrate 命令之前, 必須先執(zhí)行 flyway baseline 命令 # 設(shè)置為 true 后 flyway 將在需要 baseline 的時(shí)候, 自動(dòng)執(zhí)行一次 baseline baseline-on-migrate: true # metadata 版本控制信息表 默認(rèn) flyway_schema_history table: flyway_schema_history # 指定 baseline 的版本號(hào),默認(rèn)值為 1, 低于該版本號(hào)的 SQL 文件, migrate 時(shí)會(huì)被忽略 baseline-version: 1
創(chuàng)建腳本所在文件夾
根據(jù)上面配置文件中的腳本存放路徑,我們需要在resource目錄下建立文件夾 db/migration
sql腳本命名規(guī)范
對(duì)于Flyway,對(duì)數(shù)據(jù)庫(kù)的所有更改都稱為變遷(migrations)
- 版本變遷(Versioned Migrations): 每個(gè)版本執(zhí)行一次,包含有版本、描述和校驗(yàn)和;常用于創(chuàng)建,修改,刪除表;插入,修改數(shù)據(jù)等
- 撤銷變遷(Undo Migrations): 版本變遷(Versioned Migrations)的反操作
- 可重復(fù)變遷(Repeatable Migrations): 可以執(zhí)行多次,包含描述和校驗(yàn)和(沒(méi)有版本);主要用于視圖,存儲(chǔ)過(guò)程,函數(shù)等
- 前綴: V 代表版本變遷(Versioned Migrations), U 代表撤銷變遷(Undo Migrations), R 代表可重復(fù)變遷(Repeatable Migrations)
- 版本號(hào): 唯一的版本號(hào),比如V1.0.1
- 分隔符: __ (兩個(gè)下劃線)
- 描述信息: 描述信息
- 后綴: .sql
sql的執(zhí)行順序:
Flyway是采用了采用左對(duì)齊原則, 缺位用 0 代替,根據(jù)版本好來(lái)判斷那個(gè)sql先執(zhí)行
1.0.1.1 比 1.0.1 版本高。 1.0.10 比 1.0.9.4 版本高。 1.0.10 和 1.0.010 版本號(hào)一樣高, 每個(gè)版本號(hào)部分的前導(dǎo) 0 會(huì)被忽略
僅需要被執(zhí)行一次的SQL命名以大寫(xiě)的"V"開(kāi)頭,V+版本號(hào)(版本號(hào)的數(shù)字間以”.“或”_“分隔開(kāi))+雙下劃線(用來(lái)分隔版本號(hào)和描述)+文件描述+后綴名。
例如: V20201100__create_user.sql
、V2.1.5__create_user_ddl.sql
、V4.1_2__add_user_dml.sql
可重復(fù)運(yùn)行的SQL,則以大寫(xiě)的“R”開(kāi)頭,后面再以兩個(gè)下劃線分割,其后跟文件名稱,最后以.sql結(jié)尾。(不推薦使用)比如:R__truncate_user_dml.sql
其中,V開(kāi)頭的SQL執(zhí)行優(yōu)先級(jí)要比R開(kāi)頭的SQL優(yōu)先級(jí)高
啟動(dòng)測(cè)試
三個(gè)文件如下:
- 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
文件他就會(huì)出現(xiàn)錯(cuò)誤
[ERROR] Migration checksum mismatch for migration version 2
如果我們修改R__add_unknown_user.sql
然后再次執(zhí)行,該腳本會(huì)再次執(zhí)行,并且flyway的歷史記錄表中也會(huì)增加本次執(zhí)行的記錄
四、Flyway配置清單
flyway.baseline-description對(duì)執(zhí)行遷移時(shí)基準(zhǔn)版本的描述. flyway.baseline-on-migrate當(dāng)遷移時(shí)發(fā)現(xiàn)目標(biāo)schema非空,而且?guī)в袥](méi)有元數(shù)據(jù)的表時(shí),是否自動(dòng)執(zhí)行基準(zhǔn)遷移,默認(rèn)false. flyway.baseline-version開(kāi)始執(zhí)行基準(zhǔn)遷移時(shí)對(duì)現(xiàn)有的schema的版本打標(biāo)簽,默認(rèn)值為1. flyway.check-location檢查遷移腳本的位置是否存在,默認(rèn)false. flyway.clean-on-validation-error當(dāng)發(fā)現(xiàn)校驗(yàn)錯(cuò)誤時(shí)是否自動(dòng)調(diào)用clean,默認(rèn)false. flyway.enabled是否開(kāi)啟flywary,默認(rèn)true. flyway.encoding設(shè)置遷移時(shí)的編碼,默認(rèn)UTF-8. flyway.ignore-failed-future-migration當(dāng)讀取元數(shù)據(jù)表時(shí)是否忽略錯(cuò)誤的遷移,默認(rèn)false. flyway.init-sqls當(dāng)初始化好連接時(shí)要執(zhí)行的SQL. flyway.locations遷移腳本的位置,默認(rèn)db/migration. flyway.out-of-order是否允許無(wú)序的遷移,默認(rèn)false. flyway.password目標(biāo)數(shù)據(jù)庫(kù)的密碼. flyway.placeholder-prefix設(shè)置每個(gè)placeholder的前綴,默認(rèn)${. flyway.placeholder-replacementplaceholders是否要被替換,默認(rèn)true. flyway.placeholder-suffix設(shè)置每個(gè)placeholder的后綴,默認(rèn)}. flyway.placeholders.[placeholder name]設(shè)置placeholder的value flyway.schemas設(shè)定需要flywary遷移的schema,大小寫(xiě)敏感,默認(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遷移時(shí)使用的目標(biāo)版本,默認(rèn)為latest version flyway.url遷移時(shí)使用的JDBC URL,如果沒(méi)有指定的話,將使用配置的主數(shù)據(jù)源 flyway.user遷移數(shù)據(jù)庫(kù)的用戶名 flyway.validate-on-migrate遷移時(shí)是否校驗(yàn),默認(rèn)為true
五、maven插件的使用
上面的操作,每次我們想要migration都需要運(yùn)行整個(gè)springboot項(xiàng)目,并且只能執(zhí)行migrate一種命令,其實(shí)flyway還是有很多其它命令的,maven插件給了我們不需要啟動(dòng)項(xiàng)目就能執(zhí)行flyway各種命令的機(jī)會(huì)。
<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ù)庫(kù)Schema遷移到最新版本,是Flyway工作流的核心功能,F(xiàn)lyway在Migrate時(shí)會(huì)檢查Metadata(元數(shù)據(jù))表,如果不存在會(huì)創(chuàng)建Metadata表,Metadata表主要用于記錄版本變更歷史以及Checksum之類的
baseline
Baseline針對(duì)已經(jīng)存在Schema結(jié)構(gòu)的數(shù)據(jù)庫(kù)的一種解決方案,即實(shí)現(xiàn)在非空數(shù)據(jù)庫(kù)中新建Metadata表,并把Migrations應(yīng)用到該數(shù)據(jù)庫(kù)。
Baseline可以應(yīng)用到特定的版本,這樣在已有表結(jié)構(gòu)的數(shù)據(jù)庫(kù)中也可以實(shí)現(xiàn)添加Metadata表,從而利用Flyway進(jìn)行新Migrations的管理了
clean(慎用)
Clean相對(duì)比較容易理解,清除掉對(duì)應(yīng)數(shù)據(jù)庫(kù)Schema中所有的對(duì)象,包括表結(jié)構(gòu),視圖,存儲(chǔ)過(guò)程等,clean操作在dev 和 test階段很好用,但在生產(chǎn)環(huán)境務(wù)必禁用
info
Info用于打印所有Migrations的詳細(xì)和狀態(tài)信息,其實(shí)也是通過(guò)Metadata表和Migrations完成的,Info能夠幫助快速定位當(dāng)前的數(shù)據(jù)庫(kù)版本,以及查看執(zhí)行成功和失敗的Migrations。下圖很好地示意了Info打印出來(lái)的信息
repair
repair操作能夠修復(fù)Metadata表,該操作在Metadata表出現(xiàn)錯(cuò)誤時(shí)是非常有用的
validate
Validate是指驗(yàn)證已經(jīng)Apply的Migrations是否有變更,F(xiàn)lyway是默認(rèn)是開(kāi)啟驗(yàn)證的。
Validate原理是對(duì)比Metadata表與本地Migrations的Checksum值,如果值相同則驗(yàn)證通過(guò),否則驗(yàn)證失敗,從而可以防止對(duì)已經(jīng)Apply到數(shù)據(jù)庫(kù)的本地Migrations的無(wú)意修改
undo
撤銷操作,社區(qū)版不支持
六、flyway知識(shí)補(bǔ)充
- flyway執(zhí)行migrate必須在空白的數(shù)據(jù)庫(kù)上進(jìn)行,否則報(bào)錯(cuò)
- 對(duì)于已經(jīng)有數(shù)據(jù)的數(shù)據(jù)庫(kù),必須先baseline,然后才能migrate
- clean操作是刪除數(shù)據(jù)庫(kù)的所有內(nèi)容,包括baseline之前的內(nèi)容
- 盡量不要修改已經(jīng)執(zhí)行過(guò)的SQL,即便是R開(kāi)頭的可反復(fù)執(zhí)行的SQL,它們會(huì)不利于數(shù)據(jù)遷移
- 當(dāng)需要做數(shù)據(jù)遷移的時(shí)候,更換一個(gè)新的空白數(shù)據(jù)庫(kù),執(zhí)行下migrate命令,所有的數(shù)據(jù)庫(kù)更改都可以一步到位地遷移過(guò)去
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java獲取e.printStackTrace()打印的信息方式
這篇文章主要介紹了Java獲取e.printStackTrace()打印的信息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java實(shí)現(xiàn)的生成二維碼和解析二維碼URL操作示例
這篇文章主要介紹了Java實(shí)現(xiàn)的生成二維碼和解析二維碼URL操作,結(jié)合實(shí)例形式分析了Java創(chuàng)建與解析二維碼,以及文件讀寫(xiě)等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07解決springcloud 配置gateway 出現(xiàn)錯(cuò)誤的問(wèn)題
今天給大家分享springcloud 配置gateway 出現(xiàn)錯(cuò)誤的問(wèn)題,其實(shí)解決方法很簡(jiǎn)單,只需要降低springcloud版本,改成Hoxton.SR5就好了,再次改成Hoxton.SR12,也不報(bào)錯(cuò)了,下面給大家展示下,感興趣的朋友一起看看吧2021-11-11使用lombok注解導(dǎo)致mybatis-plus TypeHandler失效的解決
這篇文章主要介紹了使用lombok注解導(dǎo)致mybatis-plus TypeHandler失效的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07JAVA基礎(chǔ)之控制臺(tái)輸入輸出的實(shí)例代碼
下面小編就為大家?guī)?lái)一篇JAVA基礎(chǔ)之控制臺(tái)輸入輸出的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07IntelliJ IDEA查看方法說(shuō)明文檔的圖解
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA查看方法說(shuō)明文檔的圖解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10spring mvc4中相關(guān)注解的詳細(xì)講解教程
這篇文章主要給大家介紹了關(guān)于spring mvc4中相關(guān)注解的相關(guān)資料,其中詳細(xì)介紹了關(guān)于@Controller、@RequestMapping、@RathVariable、@RequestParam及@RequestBody等等注解的相關(guān)內(nèi)容,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-06-06springboot集成springdoc-openapi的案例講解(模擬前端請(qǐng)求)
文章介紹了Spring?Boot集成Swagger時(shí)版本沖突的常見(jiàn)問(wèn)題,推薦使用springdoc-openapi-ui替代Springfox,因其配置更簡(jiǎn)單且遵循OpenAPI規(guī)范,同時(shí)提供驗(yàn)證和界面優(yōu)化方法,對(duì)springboot集成springdoc-openapi相關(guān)知識(shí)感興趣的朋友一起看看吧2025-06-06