掃二維碼與項目經理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網交流
1. 前言

我們提供的服務有:成都網站制作、成都網站建設、外貿營銷網站建設、微信公眾號開發(fā)、網站優(yōu)化、網站認證、桂林ssl等。為成百上千企事業(yè)單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的桂林網站制作公司
隨著項目的不斷迭代,數據庫表結構、數據都在發(fā)生著變化。甚至有的業(yè)務在多環(huán)境版本并行運行。數據為王的時代,管理好數據庫的版本也成為了迫切的需要。如何能做到像 Git 之類的版本控制工具來管理數據庫?Java 項目中常用 Flyway 和 Liquibase 來管理數據庫版本。其中 Flyway 相對來說比較受歡迎。
2. Flyway 的特點
Flyway 大受歡迎是因為它具有以下優(yōu)點:
3. Flyway 的工作機制
Flyway 需要在 DB 中先創(chuàng)建一個 metadata 表 (缺省表名為 flyway_schema_history), 在該表中保存著每次 migration (遷移)的記錄, 記錄包含 migration 腳本的版本號和 SQL 腳本的 checksum 值。下圖表示了多個數據庫版本。
對應的 metadata 表記錄:
| 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 掃描文件系統(tǒng)或應用程序的類路徑讀取 DDL 和 DML 以進行遷移。根據metadata 表進行檢查遷移。如果腳本聲明的版本號小于或等于標記為當前版本的版本號之一,將忽略它們。其余遷移是待處理遷移:可用,但未應用。最后按版本號對它們進行排序并按順序執(zhí)行 并將執(zhí)行結果寫入 metadata 表。
對應的 metadata 表記錄:
| 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 支持命令行(需要下載命令行工具)和 Java Api ,也支持構建工具 Maven 和 Gradle 。這里我們將目光放在 Java Api 上。
3. Flyway 的規(guī)則
Flyway 是如何比較兩個 SQL 文件的先后順序呢?它采用 采用左對齊原則, 缺位用 0 代替 。舉幾個例子:
1.0.1.1 比 1.0.1 版本高。
1.0.10 比 1.0.9.4 版本高。
1.0.10 和 1.0.010 版本號一樣高, 每個版本號部分的前導 0 會被忽略。
Flyway 將 SQL 文件分為 Versioned 、Repeatable 和 Undo 三種:
這三種的命名規(guī)則如下圖:
4. Spring Boot 集成 Flyway
Spring Boot 提供了對 Flyway 的自動配置 。使我們可以開箱即用 Flyway 進行數據庫版本控制。
4.1 Flyway 依賴
你只需要引入依賴:
org.flywaydb flyway-core
當然你要集成你的相關數據庫環(huán)境。這里我們采用 H2 數據庫來演示,其它數據庫同理只不過方言不同。不熟悉 H2 數據庫的可參閱我的專題文章 Spring Boot 2 實戰(zhàn):H2數據庫集成以及使用 。
4.2 Flyway 配置
為了直觀的講解配置,首先在 Spring Boot 配置文件 application.yml 我們配置 H2 數據庫為:
- spring:
- datasource:
- # h2 驅動
- driver-class-name: org.h2.Driver
- # h2 數據庫 持久化到磁盤D:/h2 庫名: flyway mysql模式
- url: jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE
- h2:
- # 開啟console 訪問 默認false
- console:
- enabled: true
- settings:
- # 開啟h2 console 跟蹤 方便調試 默認 false
- trace: true
- # 允許console 遠程訪問 默認false
- web-allow-others: true
- # h2 訪問路徑上下文
- path: /h2-console
對應Flyway的配置為:
- # flyway 配置
- spring:
- flyway:
- # 啟用或禁用 flyway
- enabled: true
- # flyway 的 clean 命令會刪除指定 schema 下的所有 table, 生產務必禁掉。這個默認值是 false 理論上作為默認配置是不科學的。
- clean-disabled: true
- # SQL 腳本的目錄,多個路徑使用逗號分隔 默認值 classpath:db/migration
- locations: classpath:db/migration
- # metadata 版本控制信息表 默認 flyway_schema_history
- table: flyway_schema_history
- # 如果沒有 flyway_schema_history 這個 metadata 表, 在執(zhí)行 flyway migrate 命令之前, 必須先執(zhí)行 flyway baseline 命令
- # 設置為 true 后 flyway 將在需要 baseline 的時候, 自動執(zhí)行一次 baseline。
- baseline-on-migrate: true
- # 指定 baseline 的版本號,默認值為 1, 低于該版本號的 SQL 文件, migrate 時會被忽略
- baseline-version: 1
- # 字符編碼 默認 UTF-8
- encoding: UTF-8
- # 是否允許不按順序遷移 開發(fā)建議 true 生產建議 false
- out-of-order: false
- # 需要 flyway 管控的 schema list,這里我們配置為flyway 缺省的話, 使用spring.datasource.url 配置的那個 schema,
- # 可以指定多個schema, 但僅會在第一個schema下建立 metadata 表, 也僅在第一個schema應用migration sql 腳本.
- # 但flyway Clean 命令會依次在這些schema下都執(zhí)行一遍. 所以 確保生產 spring.flyway.clean-disabled 為 true
- schemas: flyway
- # 執(zhí)行遷移時是否自動調用驗證 當你的 版本不符合邏輯 比如 你先執(zhí)行了 DML 而沒有 對應的DDL 會拋出異常
- validate-on-migrate: true
請務必仔細閱讀 Flyway 相關配置的說明。
4.3 編寫 SQL 初始化腳本
我們先編寫一個初始化 SQL 文件,向 H2 數據庫已經自動初始化的 schema flyway 添加一張 sys_user 表。請注意命名規(guī)則。腳本名稱為 V1.0.1__Add_table_user.sql 。SQL 腳本的位置在配置的 spring.flyway.locations 下。內容為:
- use `flyway`;
- CREATE TABLE `sys_user`
- (
- `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `username` varchar(1024) NOT NULL unique ,
- `encode_password` varchar(1024) NOT NULL,
- `age` int(3) NOT NULL,
- PRIMARY KEY (`user_id`)
- ) ENGINE = InnoDB
- DEFAULT CHARSET = utf8mb4;
- insert into flyway.sys_user values (1,'Felordcn','{noop}12345',18);
啟動 Spring Boot 應用 。打開 H2 數據庫控制臺 http://localhost:8080/h2-console ,在 JDBC URL 一欄粘貼 jdbc:h2:file:D:/h2/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE 并點擊 Connect 按鈕會進入以下界面:
這里 -1 是因為我們缺省了 Flyway 需要的 flyway_schema_history 表 。0 是因為 H2 數據庫自動初始化了 Schema flyway ,其它數據庫可能需要你手動來建立。
4.4 編寫 SQL 變更腳本
我們編寫一個 V1.0.0__Delete_sysuser_felordcn.sql 來刪除 V1.0.1__Add_table_user.sql 中初始化的用戶。你會發(fā)現啟動報錯了,因為我們開啟了校驗,所以對于邏輯錯誤的版本會拋出異常。我們將版本號更改為 V1.0.2__Delete_sysuser_felordcn.sql 再次啟動。通過 H2 數據庫控制臺我們會發(fā)現多了一條變更記錄:
同時 sys_user 表的數據也沒有了,符合預期。
5. Flyway 最佳實踐
通過上面的介紹相信你很快就會使用 Flyway 進行數據庫版本控制了。這里總結了一些在實際開發(fā)中的使用經驗:
6. 總結
今天我們對 Flyway 數據庫版本遷移管理工具進行了介紹并將之與 Spring Boot 相結合。這將大大規(guī)范我們的數據庫管理,提高生產效率。同時也分享了一些相當有用的生產實踐經驗。

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網交流