提示:本文中,咱們只給了部分示例代碼。若是你須要完整的代碼,請點擊: https://github.com/mengyunzhi/springBootSampleCode/tree/master/flyway
在使用flyway的版本遷移功能時,若是咱們並非在項目之初就啓用flyway的話,那麼在有歷史數據的狀況下,啓用flyway
後,因爲數據庫中,並不存在flyway
所依賴的庫,因此將會出現:set baselineOnMigrate to true to initialize the schema history table
的錯誤。html
java:1.8
+ spring-boot:2.0.3.RELEASE
+ mysql:5.6
java
官方文檔:mysql
ddl-auto
設置爲create
, 而後啓用flyway
。flyway
須要使用的數據表,並導出爲scheme.sql
文件。scheme.sql
文件,導入到歷史數據庫中。flyway
flyway
數據庫在mysql
中創建flyway
數據庫。
git
flyway
依賴pom.xml
中加入flyway
github
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mengyunzhi.springBootSampleCode</groupId> <artifactId>flyway</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>flyway</name> <description>在歷史項目上使用flyway作版本遷移控制</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
在resources
中創建db/migration
文件夾,並創建V1.0__init.sql
(是__
而不是_
)。spring
V1.0__init.sqlsql
# 這是一行註釋,防止文件爲空。
spring: jpa: hibernate: ddl-auto: create datasource: username: root password: url: jdbc:mysql://127.0.0.1/flywayDemo?useUnicode=true&characterEncoding=utf-8
起動應用,此時,將在數據庫中,生成一張數據表。數據庫
在數據表上右鍵 -> 轉存爲sql
文件 -> 僅結構。而後咱們在須要使用flyway
的歷史數據庫中,將其導入便可。apache
咱們保持數據爲不動,把當前項目模擬爲歷史項目(ddl-auto: update
), 更改配置爲:maven
spring: jpa: hibernate: ddl-auto: update datasource: username: root password: url: jdbc:mysql://127.0.0.1/flywayDemo?useUnicode=true&characterEncoding=utf-8
應用成功啓動,未報錯。
上述方案,是可行的,但不夠自動化。咱們期待自動化的解決數據表的升級問題,而不是手工去作1,2,3,4..項操做。緣由很簡單,當咱們進行數據升級時,心情大都會比較緊張,就怕出錯。但越緊張就越容易出錯,若是咱們今天手動改一點,記本上,明天手動改一點,再記本上。系統一升級,手工進行1-12項改動,不免就會發生錯誤。因此,咱們要避免手動進行升級可能會發生錯誤的尷尬。
下面,咱們啓用spring boot
在初始化數據方法,在初始化數據時,增長一個函數。在函數中實現:若是有了flyway
的數據表,則跳過。若是沒有flyway
的數據表,則執行語句生成數據表。
spring: jpa: hibernate: ddl-auto: update datasource: username: root password: url: jdbc:mysql://127.0.0.1/flywayDemo?useUnicode=true&characterEncoding=utf-8 # 設置數據初始化模式爲:always initialization-mode: always # 設置 ; 的重寫符號 separator: //
-- 重寫 ; 爲 // ,在spring中,註釋掉下面一行,應該咱們在配置文件中的 separator: // 即是起的該做用 -- DELIMITER // -- 若是存在函數,則先刪除 DROP PROCEDURE IF EXISTS `FUN20180706` // -- 定義函數FUN20180706 CREATE PROCEDURE `FUN20180706` () BEGIN DECLARE hasDataTable INT; SELECT count(*) INTO hasDataTable FROM information_schema.tables WHERE (table_schema = 'flywayDemo') AND (table_name= 'flyway_schema_history'); IF hasDataTable = 0 THEN CREATE TABLE `flyway_schema_history` ( `installed_rank` int(11) NOT NULL, `version` varchar(50) DEFAULT NULL, `description` varchar(200) NOT NULL, `type` varchar(20) NOT NULL, `script` varchar(1000) NOT NULL, `checksum` int(11) DEFAULT NULL, `installed_by` varchar(100) NOT NULL, `installed_on` timestamp NOT NULL DEFAULT current_timestamp(), `execution_time` int(11) NOT NULL, `success` tinyint(1) NOT NULL, PRIMARY KEY (`installed_rank`), KEY `flyway_schema_history_s_idx` (`success`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; SET FOREIGN_KEY_CHECKS = 1; END IF; END // -- 調用函數 CALL FUN20180706() // -- 恢復重寫的;,以避免影響其它的function -- DELIMITER ;
flyway_schema_history
。項目正常啓動,並生成了flyway
的數據表。並且,該數據表中,添加了1.0版本的初始化文件。成功!
咱們接着測試:
flyway_schema_history
schema.sql
改名爲schema1.sql
報沒有找到歷史數據表的錯誤,不錯,這正是咱們期待的,這說明,生成flyway
所須要的數據表,的確是schema.sql
的功勞。
在進行開發時,若是咱們使用的爲h2
等嵌入式數據庫,每次數據表都從新生成的話,須要禁用自動執行schema1.sql
,即須要將initialization-mode:
設置爲none
。
咱們經過查看官方文檔,結合mysql
建立函數的知識,解決了在歷史表中,自動生成flyway
所須要的數據表的目標。從而使項目上線後,使用flyway
更新數據表,成爲了可能。
對於初級軟件工程師的咱們,咱們的需求其實大牛們早就解決了。成功的祕訣即是:與成功者共舞。嘗試看懂、應用官方文檔,今天你行動了嗎?
路漫漫其修遠兮,吾將上下而求索。
河北工業大學夢雲智軟件開發團隊,期待你的加入!