您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)java中如何使用Flyway管理數(shù)據(jù)庫的版本變更的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
1. 前言
隨著項目的不斷迭代,數(shù)據(jù)庫表結(jié)構(gòu)、數(shù)據(jù)都在發(fā)生著變化。甚至有的業(yè)務(wù)在多環(huán)境版本并行運行。數(shù)據(jù)為王的時代,管理好數(shù)據(jù)庫的版本也成為了迫切的需要。如何能做到像 Git 之類的版本控制工具來管理數(shù)據(jù)庫?Java 項目中常用 Flyway 和 Liquibase 來管理數(shù)據(jù)庫版本。其中 Flyway 相對來說比較受歡迎。
2. Flyway 的特點
Flyway 大受歡迎是因為它具有以下優(yōu)點:
簡單 非常容易安裝和學(xué)習(xí),同時遷移的方式也很容易被開發(fā)者接受。
專一 Flyway 專注于搞數(shù)據(jù)庫遷移、版本控制而并沒有其它副作用。
強(qiáng)大 專為連續(xù)交付而設(shè)計。讓Flyway在應(yīng)用程序啟動時遷移數(shù)據(jù)庫。
3. Flyway 的工作機(jī)制
Flyway 需要在 DB 中先創(chuàng)建一個 metadata 表 (缺省表名為 flyway_schema_history), 在該表中保存著每次 migration (遷移)的記錄, 記錄包含 migration 腳本的版本號和 SQL 腳本的 checksum 值。下圖表示了多個數(shù)據(jù)庫版本。
對應(yīng)的 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)或應(yīng)用程序的類路徑讀取 DDL 和 DML 以進(jìn)行遷移。根據(jù)metadata 表進(jìn)行檢查遷移。如果腳本聲明的版本號小于或等于標(biāo)記為當(dāng)前版本的版本號之一,將忽略它們。其余遷移是待處理遷移:可用,但未應(yīng)用。最后按版本號對它們進(jìn)行排序并按順序執(zhí)行 并將執(zhí)行結(jié)果寫入 metadata 表。
對應(yīng)的 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 ,也支持構(gòu)建工具 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 版本號一樣高, 每個版本號部分的前導(dǎo) 0 會被忽略。
Flyway 將 SQL 文件分為 Versioned 、Repeatable 和 Undo 三種:
Versioned 用于版本升級, 每個版本有唯一的版本號并只能執(zhí)行一次.
Repeatable 可重復(fù)執(zhí)行, 當(dāng) Flyway檢測到 Repeatable 類型的 SQL 腳本的 checksum 有變動, Flyway 就會重新應(yīng)用該腳本. 它并不用于版本更新, 這類的 migration 總是在 Versioned 執(zhí)行之后才被執(zhí)行。
Undo 用于撤銷具有相同版本的版本化遷移帶來的影響。但是該回滾過于粗暴,過于機(jī)械化,一般不推薦使用。一般建議使用 Versioned 模式來解決。
這三種的命名規(guī)則如下圖:
Prefix 可配置,前綴標(biāo)識,默認(rèn)值 V 表示 Versioned, R 表示 Repeatable, U 表示 Undo
Version 標(biāo)識版本號, 由一個或多個數(shù)字構(gòu)成, 數(shù)字之間的分隔符可用點 . 或下劃線 _
Separator 可配置, 用于分隔版本標(biāo)識與描述信息, 默認(rèn)為兩個下劃線 __
Description 描述信息, 文字之間可以用下劃線 _ 或空格 分隔
Suffix 可配置, 后續(xù)標(biāo)識, 默認(rèn)為 .sql
4. Spring Boot 集成 Flyway
Spring Boot 提供了對 Flyway 的自動配置 。使我們可以開箱即用 Flyway 進(jìn)行數(shù)據(jù)庫版本控制。
4.1 Flyway 依賴
你只需要引入依賴:
<!-- 無需版本號 --> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
當(dāng)然你要集成你的相關(guān)數(shù)據(jù)庫環(huán)境。這里我們采用 H2 數(shù)據(jù)庫來演示,其它數(shù)據(jù)庫同理只不過方言不同。不熟悉 H2 數(shù)據(jù)庫的可參閱我的專題文章 Spring Boot 2 實戰(zhàn):H2數(shù)據(jù)庫集成以及使用 。
4.2 Flyway 配置
為了直觀的講解配置,首先在 Spring Boot 配置文件 application.yml 我們配置 H2 數(shù)據(jù)庫為:
spring: datasource: # h3 驅(qū)動 driver-class-name: org.h3.Driver # h3 數(shù)據(jù)庫 持久化到磁盤D:/h3 庫名: flyway mysql模式 url: jdbc:h3:file:D:/h3/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE h3: # 開啟console 訪問 默認(rèn)false console: enabled: true settings: # 開啟h3 console 跟蹤 方便調(diào)試 默認(rèn) false trace: true # 允許console 遠(yuǎn)程訪問 默認(rèn)false web-allow-others: true # h3 訪問路徑上下文 path: /h3-console
對應(yīng)Flyway的配置為:
# flyway 配置 spring: flyway: # 啟用或禁用 flyway enabled: true # flyway 的 clean 命令會刪除指定 schema 下的所有 table, 生產(chǎn)務(wù)必禁掉。這個默認(rèn)值是 false 理論上作為默認(rèn)配置是不科學(xué)的。 clean-disabled: true # SQL 腳本的目錄,多個路徑使用逗號分隔 默認(rèn)值 classpath:db/migration locations: classpath:db/migration # metadata 版本控制信息表 默認(rèn) flyway_schema_history table: flyway_schema_history # 如果沒有 flyway_schema_history 這個 metadata 表, 在執(zhí)行 flyway migrate 命令之前, 必須先執(zhí)行 flyway baseline 命令 # 設(shè)置為 true 后 flyway 將在需要 baseline 的時候, 自動執(zhí)行一次 baseline。 baseline-on-migrate: true # 指定 baseline 的版本號,默認(rèn)值為 1, 低于該版本號的 SQL 文件, migrate 時會被忽略 baseline-version: 1 # 字符編碼 默認(rèn) UTF-8 encoding: UTF-8 # 是否允許不按順序遷移 開發(fā)建議 true 生產(chǎn)建議 false out-of-order: false # 需要 flyway 管控的 schema list,這里我們配置為flyway 缺省的話, 使用spring.datasource.url 配置的那個 schema, # 可以指定多個schema, 但僅會在第一個schema下建立 metadata 表, 也僅在第一個schema應(yīng)用migration sql 腳本. # 但flyway Clean 命令會依次在這些schema下都執(zhí)行一遍. 所以 確保生產(chǎn) spring.flyway.clean-disabled 為 true schemas: flyway # 執(zhí)行遷移時是否自動調(diào)用驗證 當(dāng)你的 版本不符合邏輯 比如 你先執(zhí)行了 DML 而沒有 對應(yīng)的DDL 會拋出異常 validate-on-migrate: true
請務(wù)必仔細(xì)閱讀 Flyway 相關(guān)配置的說明。
4.3 編寫 SQL 初始化腳本
我們先編寫一個初始化 SQL 文件,向 H2 數(shù)據(jù)庫已經(jīng)自動初始化的 schema flyway 添加一張 sys_user 表。請注意命名規(guī)則。腳本名稱為 V1.0.1__Add_table_user.sql 。SQL 腳本的位置在配置的 spring.flyway.locations 下。內(nèi)容為:
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 應(yīng)用 。打開 H2 數(shù)據(jù)庫控制臺 http://localhost:8080/h3-console ,在 JDBC URL 一欄粘貼 jdbc:h3:file:D:/h3/flyway;MODE=MySQL;DATABASE_TO_LOWER=TRUE 并點擊 Connect 按鈕會進(jìn)入以下界面:
這里 -1 是因為我們?nèi)笔×?Flyway 需要的 flyway_schema_history 表 。0 是因為 H2 數(shù)據(jù)庫自動初始化了 Schema flyway ,其它數(shù)據(jù)庫可能需要你手動來建立。
4.4 編寫 SQL 變更腳本
我們編寫一個 V1.0.0__Delete_sysuser_felordcn.sql 來刪除 V1.0.1__Add_table_user.sql 中初始化的用戶。你會發(fā)現(xiàn)啟動報錯了,因為我們開啟了校驗,所以對于邏輯錯誤的版本會拋出異常。我們將版本號更改為 V1.0.2__Delete_sysuser_felordcn.sql 再次啟動。通過 H2 數(shù)據(jù)庫控制臺我們會發(fā)現(xiàn)多了一條變更記錄:
同時 sys_user 表的數(shù)據(jù)也沒有了,符合預(yù)期。
5. Flyway 最佳實踐
通過上面的介紹相信你很快就會使用 Flyway 進(jìn)行數(shù)據(jù)庫版本控制了。這里總結(jié)了一些在實際開發(fā)中的使用經(jīng)驗:
生產(chǎn)務(wù)必禁 spring.flyway.cleanDisabled=false 。
盡量避免使用 Undo 模式。
開發(fā)版本號盡量根據(jù)團(tuán)隊來進(jìn)行多層次的命名避免混亂。比如 V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql ,這種命名同時也可以獲取更多腳本的開發(fā)者和相關(guān)功能的信息。
spring.flyway.outOfOrder 取值 生產(chǎn)上使用 true,開發(fā)中使用 false。
多個系統(tǒng)公用一個 數(shù)據(jù)庫 schema 時配置spring.flyway.table 為不同的系統(tǒng)設(shè)置不同的 metadata 表名而不使用缺省值 flyway_schema_history 。
感謝各位的閱讀!關(guān)于“java中如何使用Flyway管理數(shù)據(jù)庫的版本變更”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。