隨着項目不斷的增大,尤爲是一個在不斷開發完善的項目,隨着需求變化,數據庫的schema也會跟着變化,數據庫也須要不斷的擴充,加表加字段,(每一次的增長稱做一次DB的遷移migration)你是否還在用着最原始的方式, 用文件管理每次的SQL升級腳本,加了哪些字段,加了那些表,如今能夠用數據庫版本控制工具垂手可得搞定了。html
flyway支持java API的操做方式,能夠和spring 框架進行無縫鏈接,使其在系統啓動的時候檢查並升級數據庫的版本(特別適合於java項目)。java
版本:對數據庫的每一次變動可稱爲一個版本。spring
遷移:Flyway把數據庫結構從一個版本更新到另外一個版本叫作遷移。sql
可用的遷移:Flyway的文件系統識別出來的遷移版本。數據庫
已經應用的遷移:Flyway已經對數據庫執行過的遷移。tomcat
Migrate:應用全部的遷移到最新版本,它會在你的DB中新建個表schema_version
來存放每次升級的版本信息。mvc
Clean:clean all objects框架
Info:打印全部的遷移的信息以及狀態。ssh
Validate:遷移以前進行驗證。maven
Baseline:初始化schema_version
表,並插入一條原始verion=1。
Repair:它主要作了兩件事,移除全部失敗的遷移(升級),重置校驗和。
1)支持SQL(還有PL/SQL,T-SQL)文件的方式進行升級(這就是最原始的方式,可是得按照必定的規則規則,例如:V2_0_0_0__update.sql, V2_0_0_1__update.sql。
sql腳本的命名規則:
prefix: default: V (大寫哦)
version: 版本號,也可使用大小版本組合的方式,小版本號用單 _區分
separator: 分隔符,雙下劃線 __
description: 描述(你懂得,必需要有意義)
suffix: 後綴 default: .sql
2)固然也支持Java方式,繼承 JdbcMigration便可,例如我定義了一個升級的類:public class V1_2__Another_user implements JdbcMigration {} 若是你使用JVM平臺,建議你用Java API,也支持Android哦。
這兒就不詳細介紹了。這個不是重點。重點在介紹java的使用
有以下插件支持:Maven, Gradle,SBT和Ant,還有更多Plugins,提供對Spring Boot, Dropwizard, Grails, Play, Griffon, Grunt, Ninja 的支持。 其中能夠研究下flyway-test-extensions,有Usage flyway dbunit test、Usage-flyway-spring-test 功能很強大。
<properties> <flyway.version>2.3</flyway.version> </properties> <!--flyway要用到的jar包 --> <dependency> <groupId>com.googlecode.flyway</groupId> <artifactId>flyway-core</artifactId> <version>${flyway.version}</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> </dependency>
(flyway找腳本的時候默認去/src/mian/resources下面的db/migration,若是要放在別的位置,後面的地方要配置一下)
public class DatabaseFlywayMigration { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void migrate() { Flyway flyway = new Flyway(); flyway.setDataSource(dataSource); flyway.setLocations("flyway"); // 設置flyway掃描sql升級腳本、java升級腳本的目錄路徑或包路徑(表示是src/main/resources/flyway下面,前綴默認爲src/main/resources,由於這個路徑默認在classpath下面) flyway.setEncoding("UTF-8"); // 設置sql腳本文件的編碼 flyway.setOutOfOrder(true); //flyway.setDataSource(dataSource); //flyway.setSchemas("flywaydemo"); // 設置接受flyway進行版本管理的多個數據庫 // flyway.setTable("schema_version"); // 設置存放flyway metadata數據的表名 //flyway.setValidationMode(ValidationMode.ALL); // 設置執行migrate操做以前的validation行爲 //flyway.setValidationErrorMode(ValidationErrorMode.FAIL); // 設置當validation失敗時的系統行爲 // 設置當validation失敗時的系統行爲 try { flyway.setInitOnMigrate(true); flyway.migrate(); } catch (FlywayException e) { flyway.repair(); e.printStackTrace(); } } }
在ApplicationContext.xml(spring mvc的上下文中加入以下:)
<!-- flayway --> <bean id="flywayMigration1" class="com.kedacom.flyway.DatabaseFlywayMigration" init-method="migrate"> <property name="dataSource" ref="dataSource" /> </bean>
從上面的bean 定義中咱們能夠看到,咱們爲flywayMigration 這個bean 實例注入了一個數據源,Flyway 的全部操做將針對這個數據源進行;同時咱們經過init-method 屬性指定了Spring 在實例化該bean 之後,主動執行該bean 的migrate 方法,而該方法內會執行Flyway 更新數據庫的操做。
至此,咱們達到了在應用啓動時,Spring 實例化上下文的時候,在Spring 實例化flywayMigration 這個bean 的時候,自動執行Flyway 更新數據庫的操做。
可是,咱們尚未達到目的,萬一Flyway 還在更新數據庫,沒有完成更新操做以前,應用程序的其餘邏輯已經開始使用數據庫進行其餘操做了,會致使應用程序產生不少bug ,甚至根本運行不起來。
要解決這個問題,咱們能夠利用Spring 的bean 依賴原理,讓關鍵的數據庫操做bean 依賴於flywayMigration 這個bean ,達到在flywayMigration 沒有實例化完成(數據庫更新操做完成)以前,不能進行任何其餘數據庫相關操做。
利用Spring 的bean 依賴讓flywayMigration 優先處理數據庫更新操做:
<!-- 將鏈接池注入到 JdbcTemplate對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" depends-on="flywayMigration1"> <property name="dataSource" ref="dataSource"></property> </bean>
至此,運行就能夠了。
可是值得注意的是:
在啓動的tomcat的時候,內容以下:
可是在schema_version裏面已經執行過的版本號以下:
其實並無執行個人v1_0_0_0__update.sql這個腳本,
DROP TABLE if EXISTS env; -- 環境 方案 CREATE TABLE env( id varchar(36) not null, env_name varchar(50) not null, env_username varchar(30) comment '環境用戶名', env_password varchar(30) comment '環境用戶密碼', ssh_port int default 22, state varchar(30) , primary key(id) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
由於沒有建立這個數據庫表
反而是第二個版本的sql腳本給執行了 v1_0_0_1__update.sql
緣由是schema_version表的version爲1其實被flyway默認爲v1_0_0_0版本了,因此沒有執行,而version版本爲表示初始化schema_version。因此咱們能夠改成從v2_0_0_0__update.sql開始第一個sql版本。這樣就會執行了,反正flyway2.3版本是這樣的,不知道後面的版本有沒有改善這個問題。