SpringBoot + Flyway,自動(dòng)化實(shí)現(xiàn)數(shù)據(jù)庫(kù)版本控制
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??
來(lái)源:blog.csdn.net/Beijing_L/article/details/122730110
為什么使用Flyway SpringBoot集成Flyway 2.1 簡(jiǎn)單示例 2.2 常見問(wèn)題 2.3 源碼參考 總結(jié)
為什么使用Flyway
最簡(jiǎn)單的一個(gè)項(xiàng)目是一個(gè)軟件連接到一個(gè)數(shù)據(jù)庫(kù),但是大多數(shù)項(xiàng)目中我們不僅要處理我們開發(fā)環(huán)境的副本,還需要處理其他很多副本。例如:開發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境。想到數(shù)據(jù)庫(kù)管理,我們立刻就能想到一系列問(wèn)題
如何快速收集執(zhí)行腳本的清單 執(zhí)行的腳本總要人工執(zhí)行,是否可以通過(guò)機(jī)器執(zhí)行 執(zhí)行的腳本是否已經(jīng)在數(shù)據(jù)庫(kù)執(zhí)行過(guò) 執(zhí)行的腳本是否全部在數(shù)據(jù)庫(kù)中執(zhí)行過(guò) 執(zhí)行的腳本如何回退 如何初始化一個(gè)空數(shù)據(jù)庫(kù)實(shí)例
Flyway是一款數(shù)據(jù)庫(kù)版本控制管理工具,它可以簡(jiǎn)單的、可靠的升級(jí)你的數(shù)據(jù)庫(kù)。它能幫助解決上面的問(wèn)題。Flyway核心是記錄所有版本演化和狀態(tài)的MetaData,首次啟動(dòng)創(chuàng)建默認(rèn)名為SCHEMA_VERSION的元素表。表中保存了版本,描述,要執(zhí)行的sql腳本等信息。
Flyway已經(jīng)支持?jǐn)?shù)據(jù)庫(kù)包括:Oracle, SQL Server, SQL Azure, DB2, DB2 z/OS, MySQL (
including Amazon RDS), MariaDB, Google Cloud SQL, PostgreSQL (including Amazon RDS and Heroku), Redshift, Vertica, H2, Hsql, Derby, SQLite, SAP HANA, solidDB, Sybase ASE and Phoeni
官網(wǎng)鏈接:https://flywaydb.org/
SpringBoot集成Flyway
2.1 簡(jiǎn)單示例
參考版本信息

參考目錄結(jié)構(gòu)

1.創(chuàng)建SpringBoot應(yīng)用,并添加flyway-core依賴,本例中將實(shí)現(xiàn)初始化腳本到mysql數(shù)據(jù)庫(kù),因此同時(shí)引入了驅(qū)動(dòng)依賴 mysql-connector-java
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
參考pom.xml依賴如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
2.在application.properties中設(shè)置flyway信息
server.port=7002
##是否啟動(dòng),默認(rèn)開啟
spring.flyway.enabled = true
##腳本存放路徑
spring.flyway.locations = classpath:db/migration
##當(dāng)flyway第一次運(yùn)行時(shí),會(huì)在我們對(duì)應(yīng)的數(shù)據(jù)庫(kù)中新建一個(gè)記錄腳本運(yùn)行情況的
spring.flyway.table=flyway_schema_history
# flyway指向的數(shù)據(jù)庫(kù)鏈接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/runoob?useUnicode=true&characterEncoding=utf8
# 用戶名
spring.flyway.user=nacos
# 密碼
spring.flyway.password=nacos
# 數(shù)據(jù)庫(kù)驅(qū)動(dòng)
spring.flyway.driver-class-name=com.mysql.cj.jdbc.Driver
3.腳本整理
將腳本整理到resource/db.migration路徑下,例如

參考SQL腳本信息如下
//V1.20190621.1854__CREATE_PERSION_TABLE.sql腳本內(nèi)容
create table PERSON (
ID int not null,
NAME varchar(100) not null
);
//V1.20190621.1904__INIT_PERSION.sql 腳本內(nèi)容
insert into PERSON (ID, NAME) values (1, 'Axel');
insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
sql 目錄中存放腳本文件,腳本名稱命名方式
版本化遷移 :執(zhí)行一遍,版本號(hào)唯一,有重復(fù)會(huì)報(bào)錯(cuò):格式:V+版本號(hào) +雙下劃線+描述+結(jié)束符 重復(fù)的遷移 ,不需要版本號(hào),腳本發(fā)生變化啟動(dòng)就會(huì)執(zhí)行:格式:R+雙下劃線+描述+結(jié)束符 撤消遷移 :格式:U+版本號(hào) +雙下劃線+描述+結(jié)束符

4.運(yùn)行啟動(dòng)主類,運(yùn)行日志如下,從日志中可以看到如下信息
啟動(dòng)后正確鏈接到數(shù)據(jù)庫(kù)runoob 驗(yàn)證2個(gè)遷移腳本成功 使用命令行的方式創(chuàng)建了一張名稱為 flyway_schema_history的記錄表,這里要注意,所有腳本一旦執(zhí)行了就會(huì)在flyway_schema_history中創(chuàng)建記錄, 如果出錯(cuò)引發(fā)問(wèn)題,可以刪除表中記錄,反正啟動(dòng)的時(shí)候還會(huì)再執(zhí)行,當(dāng)然生產(chǎn)環(huán)境不建議此方法,但生產(chǎn)環(huán)境上部署的包都是驗(yàn)證過(guò)無(wú)問(wèn)題的包也不會(huì)出現(xiàn)此問(wèn)題執(zhí)行了 resource/db.migration目錄下的兩個(gè)腳本,并執(zhí)行成功
INFO 190688 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 7.15.0 by Redgate
INFO 190688 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:mysql://127.0.0.1:3306/runoob (MySQL 5.7)
INFO 190688 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 2 migrations (execution time 00:00.016s)
INFO 190688 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table `runoob`.`flyway_schema_history` with baseline ...
INFO 190688 --- [ main] o.f.core.internal.command.DbBaseline : Successfully baselined schema with version: 1
INFO 190688 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema `runoob`: 1
INFO 190688 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema `runoob` to version "1.20190621.1854 - CREATE PERSION TABLE"
INFO 190688 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema `runoob` to version "1.20190621.1904 - INIT PERSION"
INFO 190688 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 2 migrations to schema `runoob`, now at version v1.20190621.1904 (execution time 00:00.225s)
停止服務(wù)后,重新運(yùn)行日志如下,從日志中可以看到信息
啟動(dòng)后正確鏈接到數(shù)據(jù)庫(kù)runoob 驗(yàn)證2個(gè)遷移腳本成功 本次沒有重復(fù)執(zhí)行腳本, 日志中打印當(dāng)前腳本編號(hào) 20190621.1904, 即最后1次執(zhí)行的腳本
INFO 193184 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 7.15.0 by Redgate
INFO 193184 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:mysql://127.0.0.1:3306/runoob (MySQL 5.7)
INFO 193184 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 3 migrations (execution time 00:00.024s)
INFO 193184 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema `runoob`: 1.20190621.1904
INFO 193184 --- [ main] o.f.core.internal.command.DbMigrate : Schema `runoob` is up to date. No migration necessary.
查看Mysql數(shù)據(jù)庫(kù)

2.2 常見問(wèn)題
1.Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s)
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) `runoob` but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
at org.flywaydb.core.Flyway$1.execute(Flyway.java:200) ~[flyway-core-7.15.0.jar:na]
at org.flywaydb.core.Flyway$1.execute(Flyway.java:170) ~[flyway-core-7.15.0.jar:na]
at org.flywaydb.core.Flyway.execute(Flyway.java:586) ~[flyway-core-7.15.0.jar:na]
問(wèn)題原因:第一執(zhí)行的時(shí)候沒有找到schema history table ,這張表其實(shí)就是application.properties文件中spring.flyway.table屬性配置的表,因此要么使用命令創(chuàng)建一個(gè)或者在application.properties文件中設(shè)置 spring.flyway.baseline-on-migrate=true,
2.Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 5.7
Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 5.7
at org.flywaydb.core.internal.database.DatabaseTypeRegister.getDatabaseTypeForConnection(DatabaseTypeRegister.java:106) ~[flyway-core-8.4.2.jar:na]
at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:75) ~[flyway-core-8.4.2.jar:na]
at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:143) ~[flyway-core-8.4.2.jar:na]
at org.flywaydb.core.Flyway.migrate(Flyway.java:124) ~[flyway-core-8.4.2.jar:na]
問(wèn)題原因:flyway-core對(duì)數(shù)據(jù)庫(kù)版本有要求,例如flyway-core的當(dāng)前最高版本V8.4.3,不能使用 MySQL 5.7, 當(dāng)flyway-core 降低到V7.15.0后 問(wèn)題解決,所以匹配flyway-core和數(shù)據(jù)庫(kù)版本后問(wèn)題即可解決
2.3 源碼參考
https://github.com/PNZBEIJINGL/springboot
總結(jié)
本文介紹了Springboot集成flyway方式
使用Flyway之前部署腳本方式一般為開發(fā)人員按照順序匯總數(shù)據(jù)庫(kù)的升級(jí)腳, 然后DBA或者售后在生產(chǎn)庫(kù)中按照順序執(zhí)行升級(jí)腳本。 使用Flyway之后部署腳本方式就變更為開發(fā)人員將腳本構(gòu)建到程序包中, 部署程序包后啟動(dòng)時(shí)Flyway自動(dòng)執(zhí)行腳本升級(jí)
1. 面試官:你說(shuō)說(shuō) Mysql 索引失效有哪些場(chǎng)景?
2. Kubernetes 缺少的多租戶功能,你可以通過(guò)這些方式實(shí)現(xiàn)
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過(guò)內(nèi)容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標(biāo)”,這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。
點(diǎn)“在看”支持小哈呀,謝謝啦

