原文地址:Flyway 簡單入門教程
博客地址:http://www.extlight.comhtml
Flyway 是一款開源的數據庫版本管理工具,它更傾向於規約優於配置的方式。Flyway 能夠獨立於應用實現管理並跟蹤數據庫變動,支持數據庫版本自動升級,而且有一套默認的規約,不須要複雜的配置,Migrations 能夠寫成 SQL 腳本,也能夠寫在 Java 代碼中,不只支持 Command Line 和 Java API,還支持 Build 構建工具和 Spring Boot 等,同時在分佈式環境下可以安全可靠地升級數據庫,同時也支持失敗恢復等。java
普通 SQL:純 SQL 腳本(包括佔位符替換)沒有專有的XML格式,沒有鎖定 無限制:使用 Java 代碼來進行一些高級數據操做 零依賴:只需運行在 Java6(及以上)和數據庫所需的 JDBC 驅動 約定優於配置:遷移時,自動查找系統文件和類路徑中的 SQL 文件或 Java 類 高可靠性:在集羣環境下進行數據庫升級是安全可靠的 雲支持:徹底支持 Microsoft SQL Azure, Google Cloud SQL & App Engine、Heroku Postgres 和 Amazon RDS 自動遷移:使用 Flyway 提供的 API,讓應用啓動和遷移同時工做 快速失敗:損壞的數據庫或失敗的遷移能夠防止應用程序啓動 數據庫清理:在一個數據庫中刪除全部的表、視圖、觸發器,而不是刪除數據庫自己
當 Flyway 鏈接數據庫中的 schema 後,會先檢查是否已存在 flyway_schema_history 表,若是沒有則建立。該表用於跟蹤數據庫的狀態,如數據遷移的版本,遷移成功狀態等信息。mysql
當 flyway_schema_history 存在後,Flyway 會掃描文件系統或應用中的 classpath 目錄的數據遷移文件,而後根據它們的版本號進行按序遷移,以下圖:spring
flyway_schema_history 表記錄的內容以下:sql
installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | Initial Setup | SQL | V1__Initial_Setup.sql | 1996767037 | axel | 2016-02-04 22:23:00.0 | 546 | true |
2 | 2 | First Changes | SQL | V2__First_Changes.sql | 1279644856 | axel | 2016-02-06 09:18:00.0 | 127 | true |
因爲 flyway_schema_history 表中記錄了遷移的版本號,若是文件的版本號小於或等於標記爲當前版本的版本號,則忽略它們不執行。數據庫
上邊描述的內容或許對讀者來講還不夠直觀,那麼下面咱們就開始進行實戰演練。api
測試環境:Mysql5.7安全
新建一個 Maven 項目。app
<!-- flyway --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>5.2.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency>
在項目的 src/main/resources 下建立 db/migration 目錄,該目錄下放置須要數據遷移的文件。分佈式
數據遷移文件名稱格式爲:**V[version]__[name].sql**。
注意:名稱中[version]和[name]之間是兩個下劃線!
本次測試新建名爲 V1__Create_person_table.sql 的文件,內容以下:
create table PERSON ( ID int not null, NAME varchar(100) not null );
版本 1 數據遷移的內容是建立一張 PERSON 表。
public class FlywayTest { public static void main(String[] args) { String url = "jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8"; String user = "root"; String password = "tiger"; Flyway flyway = Flyway.configure().dataSource(url, user, password).load(); // 建立 flyway_schema_history 表 // flyway.baseline(); // 刪除 flyway_schema_history 表中失敗的記錄 // flyway.repair(); // 檢查 sql 文件 // flyway.validate(); // 執行數據遷移 flyway.migrate(); // 刪除當前 schema 下全部表 // flyway.clean(); } }
執行結果以下圖:
圖中,數據庫 flyway 中建立了 flyway_schema_history 表和 PERSON 表,數據成功遷移到指定數據庫中。
當系統升級時又須要作數據遷移,咱們只需在 db/migration 目錄下再放置新版本的 sql 文件便可。
好比,咱們再新建一個名爲 V2__Add_people.sql 文件,內容以下:
insert into PERSON (ID, NAME) values (1, 'Axel'); insert into PERSON (ID, NAME) values (2, 'Mr. Foo'); insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
版本 2 的數據遷移內容是往 PERSON 表中插入 3 條數據。
再次執行上邊的程序,演示效果圖以下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8 username: root password: tiger flyway: enabled: true # 禁止清理數據庫表 clean-disabled: true # 若是數據庫不是空表,須要設置成 true,不然啓動報錯 baseline-on-migrate: true # 與 baseline-on-migrate: true 搭配使用 baseline-version: 0 locations: - classpath:db/migration/mysql(根據我的狀況設置)
將需數據遷移的 sql 文件放置到 db/migration/mysql 目錄中,啓動 Spring Boot 項目便可運行 Flyway 進行數據遷移。
測試結果同上,此處再也不張貼。
注意事項:
若是 flyway 不是項目初期引入,而是在數據庫已有表的狀況下引入時必須設置 baseline-on-migrate: true,設置該配置啓動項目後,flyway 就會在數據庫中建立 flyway_schema_history 表,而且會往該表中插入一條 version = 1 的建表記錄,若是遷移數據有 V1__ 開頭的文件,掃描文件會忽略該文件不執行遷移,進而可能引起其餘遷移數據出錯的問題。
以上邊的 2 個 sql 文件爲例進行演示,flyway 庫中已有一張 test 表,運行程序結果以下:
因爲忽略了 V1__Create_person_table.sql ,庫中就不建立 PERSON 表,在遷移 V2__Add_people.sql 文件中的數據時必然失敗。
解決方案先刪除flyway_schema_history 表, 而後配置文件中設置 baseline-version: 0,或修改數據遷移文件版本名稱,最後再次啓動應用便可。