一.什么是Flyway?
Flayway是一款數據庫版本控制管理工具,支持數據庫版本自動升級,Migrations可以寫成sql腳本,也可以寫在java代碼里;不僅支持Command Line和java api ,也支持Build構建工具和Spring boot,也可以在分布式環境下能夠安全可靠安全地升級數據庫,同時也支持失敗恢復。
Flyway最核心的就是用於記錄所有版本演化和狀態的MetaData表,Flyway首次啟動會創建默認名為SCHEMA_VERSION的元素局表。 表中保存了版本,描述,要執行的sql腳本等;
為什么使用Flyway?
通常在項目開始時會針對數據庫進行全局設計,但在開發產品新特性過程中,難免會遇到需要更新數據庫Schema的情況,比如:添加新表,添加新字段和約束等,這種情況在實際項目中也經常發生。
那么,當開發人員完成了對數據庫更的SQL腳本后,如何快速地在其他開發者機器上同步?並且如何在測試服務器上快速同步?以及如何保證集成測試能夠順利執行並通過呢?
假設以Spring Boot技術棧項目為例,可能有人會說,本地使用Hibernate自動更新數據庫Schema模式,然后讓QA或DEV到測試服務器上手動執行SQL腳本,同時可以寫一個Gradle任務自動執行更新。
個人覺得,對於Hibernate自動更新數據庫,感覺不靠譜,不透明,控制自由度不高,而且有時很容易就會犯錯,比如:用SQL創建的某個字段為VARCHAR類型,而在Entity中配置的為CHAR類型,那么在運行集成測試時,
自動創建的數據庫表中的字段為CHAR類型,而實際SQL腳本期望的是VARCHAR類型,雖然測試通過了,但不是期望的行為,並且在本地bootRun或服務器上運行Service時都會失敗。
另外,到各測試服務器上手動執行SQL腳本費時費神費力的,干嘛不自動化呢,當然,對於高級別和PROD環境,還是需要DBA手動執行的。最后,寫一段自動化程序來自動執行更新,想法是很好的,
那如果已經有了一些插件或庫可以幫助你更好地實現這樣的功能,為何不好好利用一下呢,當然,如果是為了學習目的,重復造輪子是無可厚非的。
其實,以上問題可以通過Flyway工具來解決,Flyway可以實現自動化的數據庫版本管理,並且能夠記錄數據庫版本更新記錄
二,怎么使用Flyway(這里使用Springboot整合Flyway)
1.引入Maven依賴 和 插件(可選,插件是作用是:不需要啟動項目就能執行Flyway各種命令)
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>5.0.3</version> </dependency> <plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>5.0.3</version> </plugin>
此時,我們雙擊執行上圖中的flyway:migrate的效果和啟動整個工程執行migrate的效果是一樣的。
其它命令的作用如下列出,各位可自行實驗體會:
-
-
baseline
對已經存在數據庫Schema結構的數據庫一種解決方案。實現在非空數據庫新建MetaData表,並把Migrations應用到該數據庫;也可以在已有表結構的數據庫中實現添加Metadata表。
-
clean
清除掉對應數據庫Schema中所有的對象,包括表結構,視圖,存儲過程等,clean操作在dev 和 test階段很好用,但在生產環境務必禁用。
-
info
用於打印所有的Migrations的詳細和狀態信息,也是通過MetaData和Migrations完成的,可以快速定位當前的數據庫版本。
-
repair
repair操作能夠修復metaData表,該操作在metadata出現錯誤時很有用。
-
undo
撤銷操作,社區版不支持。
-
validate
驗證已經apply的Migrations是否有變更,默認開啟的,原理是對比MetaData表與本地Migrations的checkNum值,如果值相同則驗證通過,否則失敗。
-
2.編輯Flyway相關的配置文件
server.port=8088 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3.在classpath下新建/db/migration文件夾,用於存放SQL腳本
4.創建我們所需要的並且需要同步數據庫的SQL腳本
注意文件的命名規則:
這里有兩類文件:
1.僅需要被執行一次的SQL命名以大寫的V開頭,后面跟上0-9數字的組合,數字之間可以用"."或者下划線"_"分割開,然后在以兩個下划線分割,其后跟文件名稱,最后以.sql結尾,
如,V2.1.5__create_user_ddl.sql
、V4.1_2__add_user_dml.sql
。
2.可重復運行的SQL,則以則以大寫的“R”開頭,后面再以兩個下划線分割,其后跟文件名稱,最后以.sql結尾。
比如,R__truncate_user_dml.sql
。
其中,V開頭的SQL執行優先級要比R開頭的SQL優先級高。
use testdb; CREATE TABLE person ( id int(11) NOT NULL AUTO_INCREMENT, first varchar(100) NOT NULL, last varchar(100) NOT NULL, dateofbirth DATE DEFAULT null, placeofbirth varchar(100) not null, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into person (first,last,dateofbirth,placeofbirth) values('Dursun','KOC', STR_TO_DATE('02/10/1982', '%m/%d/%Y'),'Erzincan'); insert into person (first,last,dateofbirth,placeofbirth) values('Durseeun','KeeOC', STR_TO_DATE('05/10/1982', '%m/%d/%Y'),'Erzeeincan');
三.Flyway的配置清單
flyway.baseline-description對執行遷移時基准版本的描述.
flyway.baseline-on-migrate當遷移時發現目標schema非空,而且帶有沒有元數據的表時,是否自動執行基准遷移,默認false.
flyway.baseline-version開始執行基准遷移時對現有的schema的版本打標簽,默認值為1.
flyway.check-location檢查遷移腳本的位置是否存在,默認false.
flyway.clean-on-validation-error當發現校驗錯誤時是否自動調用clean,默認false.
flyway.enabled是否開啟flywary,默認true.
flyway.encoding設置遷移時的編碼,默認UTF-8.
flyway.ignore-failed-future-migration當讀取元數據表時是否忽略錯誤的遷移,默認false.
flyway.init-sqls當初始化好連接時要執行的SQL.
flyway.locations遷移腳本的位置,默認db/migration.
flyway.out-of-order是否允許無序的遷移,默認false.
flyway.password目標數據庫的密碼.
flyway.placeholder-prefix設置每個placeholder的前綴,默認${.
flyway.placeholder-replacementplaceholders是否要被替換,默認true.
flyway.placeholder-suffix設置每個placeholder的后綴,默認}.
flyway.placeholders.[placeholder name]設置placeholder的value
flyway.schemas設定需要flywary遷移的schema,大小寫敏感,默認為連接默認的schema.
flyway.sql-migration-prefix遷移文件的前綴,默認為V.
flyway.sql-migration-separator遷移腳本的文件名分隔符,默認__
flyway.sql-migration-suffix遷移腳本的后綴,默認為.sql
flyway.tableflyway使用的元數據表名,默認為schema_version
flyway.target遷移時使用的目標版本,默認為latest version
flyway.url遷移時使用的JDBC URL,如果沒有指定的話,將使用配置的主數據源
flyway.user遷移數據庫的用戶名
flyway.validate-on-migrate遷移時是否校驗,默認為true
參考文章:
https://www.jianshu.com/p/567a8a161641
https://blog.csdn.net/u014091123/article/details/78133522