如果你是一個縣長,吃著火鍋唱著歌,突然就被麻匪給劫了。
Flyway簡介
總結:Flyway可以很方便的幫我們完成資料庫部署和增量升級,很有用,但是版本回滾操作並不給力~~~
1、簡介
1.1、Flyway是什麼
Flyway是一款資料庫遷移(migration)工具。簡單點說,就是在你部署應用的時候,幫你執行資料庫指令碼的工具。Flyway支援SQL和Java兩種型別的指令碼,你可以將指令碼打包到應用程式中,在應用程式啟動時,由Flyway來管理這些指令碼的執行,這些指令碼被Flyway稱之為migration。
就目前而言,我們部署應用的流程大概是這樣的:
- 開發人員將應用程式打包、按順序彙總並整理資料庫升級指令碼
- DBA拿到資料庫升級指令碼檢查、備份、執行,以完成資料庫升級
- 應部署人員拿到應用部署包,備份、替換,以完成應用程序升級
引入Flyway之後的應用部署流程大概是這樣的:
- 開發人員將應用程式打包
- 應部署人員拿到應用部署包,備份、替換,以完成應用程序升(Flyway將自動執行升級/備份指令碼)
1.1、Flyway如何工作
最簡單的理解方式是:簡單我們在一個空資料庫上部署集成了Flyway的應用:
Flyway將在這個空資料中建立一張表,用於記錄migration的執行情況,表名稱預設為:flyway_schema_histor,老版本的表名稱:schema_version
緊接著,Flyway根據表中的記錄決定是否執行應用程式包中提供的migration
最後將執行結果寫入flyway_schema_histor並校驗執行結果
下次版本迭代時,提供新的migration,會根據flyway_schema_histor的記錄執行新migration
2、核心概念
2.1、Migration
Flyway將每一個數據庫指令碼稱之為:migrations,flyway支援三種類型的migration:
- Versioned migrations:最常用的migration,可以簡單的理解為資料庫升級指令碼
- Undo migrations:資料庫版本回退指令碼,需要Pro版本,忽略,而且使用過程存在較大風險,undo操作目前只能通過plugin或者command-line來執行
- Repeatable migrations:可重複執行的migration,例如create or replace指令碼,當指令碼checksums改變時會重新執行
每個migration支援兩種編寫方式:
- Java:通過實現
org.flywaydb.core.api.migration.jdbc.JdbcMigratio
介面來建立一個Java migration,也就是通過JDBC來執行SQL,對於類是CLOB或者BOLB這種不方便在SQL中實現的指令碼比較有用,例如:
package db.migration;
import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
import java.sql.Connection;
import java.sql.PreparedStatement;
/**
* Example of a Java-based migration.
*/
public class V1_2__Another_user implements JdbcMigration {
public void migrate(Connection connection) throws Exception {
PreparedStatement statement = connection.prepareStatement("INSERT INTO test_user (name) VALUES ('Obelix')");
try {
statement.execute();
} finally {
statement.close();
}
}
}
- SQL:簡單的SQL指令碼檔案,例如:
/* Single line comment */
CREATE TABLE test_user (
name VARCHAR(25) NOT NULL,
PRIMARY KEY(name)
);
/*
Multi-line
comment
*/
-- Placeholder
INSERT INTO ${tableName} (name) VALUES ('Mr. T');
所有的migration都需要遵守命名規範:
確保版本號唯一,flyway按照版本號順序執行。repeatable沒有版本號,因為repeatable migrations會在內容改變時重複執行
預設情況下,flyway會將單個migration放在一個事物裡執行,也可以通過配置將所有migration放在同一個事物裡執行,感覺用處不大,這裡就不介紹了~
2.2、Callbacks
Flyway在執行migrations時提供了一些列的hook,使你可以在執行過程中加入額外的操作:
這些hook均執行SQL和Java型別的migrations,只需要將migration的名稱以hook名稱開頭即可,例如:beforeMigrate.sql
、beforeEachMigrate.sql
、 beforeRepair__vacuum.sql
,Java型別的hook需要實現介面:org.flywaydb.core.api.callback.Callback
2.3、Error Handlers
2.4、Dry Runs
3、使用事例
3.1、整合Spring Boot
- build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.0.2.RELEASE'
}
group 'com.chenlei'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.2.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.0.2.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
compile group: 'org.flywaydb', name: 'flyway-core', version: '5.1.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
- application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://192.168.119.123:3306/flyway?useUnicode=true&characterEncoding=utf8&useSSL=false
username: flyway
password: Flyway@1234
driver-class-name: com.mysql.jdbc.Driver
flyway:
locations: classpath:com/chenlei/flyway/db/mysql
3.2、Gradle外掛
- build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.0.2.RELEASE'
id "org.flywaydb.flyway" version "5.1.1"
}
flyway {
url = 'jdbc:mysql://192.168.119.123:3306/flyway?useUnicode=true&characterEncoding=utf-8&useSSL=false'
user = 'flyway'
password = '[email protected]'
locations = ['classpath:com/chenlei/flyway/db/mysql']
encoding = 'UTF-8'
}
group 'com.chenlei'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.2.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.0.2.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
compile group: 'org.flywaydb', name: 'flyway-core', version: '5.1.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
注意:
- Clean會將資料庫schema下的所有內容清空,謹慎執行
- Baseline的版本號和migration衝突時,migration不會執行
- Repeatable僅在check sum傳送改變時會再次執行,Java migration需要實現
org.flywaydb.core.api.migration.MigrationInfoProvider
介面 - Gradle查詢無法執行實現
org.flywaydb.core.api.migration.spring.SpringJdbcMigration
介面的migrations,只能是實現org.flywaydb.core.api.migration.jdbc.JdbcMigration
的migrations - Undo需要Pro版本
Maven外掛與此類似~