快速掌握和使用Flyway的詳細(xì)教程
什么是Flyway?
轉(zhuǎn)載:https://blog.waterstrong.me/flyway-in-practice/
Flyway is an open-source database migration tool. It strongly favors simplicity and convention over configuration.
Flyway是一款開源的數(shù)據(jù)庫(kù)版本管理工具,它更傾向于規(guī)約優(yōu)于配置的方式。Flyway可以獨(dú)立于應(yīng)用實(shí)現(xiàn)管理并跟蹤數(shù)據(jù)庫(kù)變更,支持?jǐn)?shù)據(jù)庫(kù)版本自動(dòng)升級(jí),并且有一套默認(rèn)的規(guī)約,不需要復(fù)雜的配置,Migrations可以寫成SQL腳本,也可以寫在Java代碼中,不僅支持Command Line和Java API,還支持Build構(gòu)建工具和Spring Boot等,同時(shí)在分布式環(huán)境下能夠安全可靠地升級(jí)數(shù)據(jù)庫(kù),同時(shí)也支持失敗恢復(fù)等。
Flyway主要基于6種基本命令:Migrate,Clean,Info,Validate,BaselineandRepair,稍候會(huì)逐一分析講解。目前支持的數(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 Phoenix.
關(guān)于Flyway的優(yōu)勢(shì),支持的數(shù)據(jù)庫(kù)以及與其他數(shù)據(jù)庫(kù)版本工具的對(duì)比,可以閱讀Flyway官網(wǎng)介紹。
為什么使用Flyway?
通常在項(xiàng)目開始時(shí)會(huì)針對(duì)數(shù)據(jù)庫(kù)進(jìn)行全局設(shè)計(jì),但在開發(fā)產(chǎn)品新特性過程中,難免會(huì)遇到需要更新數(shù)據(jù)庫(kù)Schema的情況,比如:添加新表,添加新字段和約束等,這種情況在實(shí)際項(xiàng)目中也經(jīng)常發(fā)生。那么,當(dāng)開發(fā)人員完成了對(duì)數(shù)據(jù)庫(kù)更的SQL腳本后,如何快速地在其他開發(fā)者機(jī)器上同步?并且如何在測(cè)試服務(wù)器上快速同步?以及如何保證集成測(cè)試能夠順利執(zhí)行并通過呢?
假設(shè)以Spring Boot技術(shù)棧項(xiàng)目為例,可能有人會(huì)說,本地使用Hibernate自動(dòng)更新數(shù)據(jù)庫(kù)Schema模式,然后讓QA或DEV到測(cè)試服務(wù)器上手動(dòng)執(zhí)行SQL腳本,同時(shí)可以寫一個(gè)Gradle任務(wù)自動(dòng)執(zhí)行更新。
個(gè)人覺得,對(duì)于Hibernate自動(dòng)更新數(shù)據(jù)庫(kù),感覺不靠譜,不透明,控制自由度不高,而且有時(shí)很容易就會(huì)犯錯(cuò),比如:用SQL創(chuàng)建的某個(gè)字段為VARCHAR類型,而在Entity中配置的為CHAR類型,那么在運(yùn)行集成測(cè)試時(shí),自動(dòng)創(chuàng)建的數(shù)據(jù)庫(kù)表中的字段為CHAR類型,而實(shí)際SQL腳本期望的是VARCHAR類型,雖然測(cè)試通過了,但不是期望的行為,并且在本地bootRun或服務(wù)器上運(yùn)行Service時(shí)都會(huì)失敗。另外,到各測(cè)試服務(wù)器上手動(dòng)執(zhí)行SQL腳本費(fèi)時(shí)費(fèi)神費(fèi)力的,干嘛不自動(dòng)化呢,當(dāng)然,對(duì)于高級(jí)別和PROD環(huán)境,還是需要DBA手動(dòng)執(zhí)行的。最后,寫一段自動(dòng)化程序來自動(dòng)執(zhí)行更新,想法是很好的,那如果已經(jīng)有了一些插件或庫(kù)可以幫助你更好地實(shí)現(xiàn)這樣的功能,為何不好好利用一下呢,當(dāng)然,如果是為了學(xué)習(xí)目的,重復(fù)造輪子是無可厚非的。
其實(shí),以上問題可以通過Flyway工具來解決,F(xiàn)lyway可以實(shí)現(xiàn)自動(dòng)化的數(shù)據(jù)庫(kù)版本管理,并且能夠記錄數(shù)據(jù)庫(kù)版本更新記錄,F(xiàn)lyway官網(wǎng)對(duì)Why database migrations結(jié)合示例進(jìn)行了詳細(xì)的闡述,有興趣可以參閱一下。
Flyway如何工作的?
Flyway對(duì)數(shù)據(jù)庫(kù)進(jìn)行版本管理主要由Metadata表和6種命令完成,Metadata主要用于記錄元數(shù)據(jù),每種命令功能和解決的問題范圍不一樣,以下分別對(duì)metadata表和這些命令進(jìn)行闡述,其中的示意圖都來自Flyway的官方文檔。
Metadata Table
Flyway中最核心的就是用于記錄所有版本演化和狀態(tài)的Metadata表,在Flyway首次啟動(dòng)時(shí)會(huì)創(chuàng)建默認(rèn)名為SCHEMA_VERSION的元數(shù)據(jù)表,其表結(jié)構(gòu)為(以MySQL為例):
| Field | Type | Null | Key | Default |
|---|---|---|---|---|
| version_rank | int(11) | NO | MUL | NULL |
| installed_rank | int(11) | NO | MUL | NULL |
| version | varchar(50) | NO | PRI | NULL |
| description | varchar(200) | NO | NULL | |
| type | varchar(20) | NO | NULL | |
| script | varchar(1000) | NO | NULL | |
| checksum | int(11) | YES | NULL | |
| installed_by | varchar(100) | NO | NULL | |
| installed_on | timestamp | NO | CURRENT_TIMESTAMP | |
| execution_time | int(11) | NO | NULL | |
| success | tinyint(1) | NO | MUL | NULL |
Flyway官網(wǎng)上提供了一個(gè)很清晰的示例How Flyway works,可以參閱一下。
Migrate
Migrate是指把數(shù)據(jù)庫(kù)Schema遷移到最新版本,是Flyway工作流的核心功能,F(xiàn)lyway在Migrate時(shí)會(huì)檢查Metadata(元數(shù)據(jù))表,如果不存在會(huì)創(chuàng)建Metadata表,Metadata表主要用于記錄版本變更歷史以及Checksum之類的。

Migrate時(shí)會(huì)掃描指定文件系統(tǒng)或Classpath下的Migrations(可以理解為數(shù)據(jù)庫(kù)的版本腳本),并且會(huì)逐一比對(duì)Metadata表中的已存在的版本記錄,如果有未應(yīng)用的Migrations,F(xiàn)lyway會(huì)獲取這些Migrations并按次序Apply到數(shù)據(jù)庫(kù)中,否則不需要做任何事情。另外,通常在應(yīng)用程序啟動(dòng)時(shí)應(yīng)默認(rèn)執(zhí)行Migrate操作,從而避免程序和數(shù)據(jù)庫(kù)的不一致性。
Clean
Clean相對(duì)比較容易理解,即清除掉對(duì)應(yīng)數(shù)據(jù)庫(kù)Schema中的所有對(duì)象,包括表結(jié)構(gòu),視圖,存儲(chǔ)過程,函數(shù)以及所有的數(shù)據(jù)等都會(huì)被清除。

Clean操作在開發(fā)和測(cè)試階段是非常有用的,它能夠幫助快速有效地更新和重新生成數(shù)據(jù)庫(kù)表結(jié)構(gòu),但特別注意的是:不應(yīng)在Production的數(shù)據(jù)庫(kù)上使用!
Info
Info用于打印所有Migrations的詳細(xì)和狀態(tài)信息,其實(shí)也是通過Metadata表和Migrations完成的,下圖很好地示意了Info打印出來的信息。

Info能夠幫助快速定位當(dāng)前的數(shù)據(jù)庫(kù)版本,以及查看執(zhí)行成功和失敗的Migrations。
Validate
Validate是指驗(yàn)證已經(jīng)Apply的Migrations是否有變更,F(xiàn)lyway是默認(rèn)是開啟驗(yàn)證的。

Validate原理是對(duì)比Metadata表與本地Migrations的Checksum值,如果值相同則驗(yàn)證通過,否則驗(yàn)證失敗,從而可以防止對(duì)已經(jīng)Apply到數(shù)據(jù)庫(kù)的本地Migrations的無意修改。
Baseline
Baseline針對(duì)已經(jīng)存在Schema結(jié)構(gòu)的數(shù)據(jù)庫(kù)的一種解決方案,即實(shí)現(xiàn)在非空數(shù)據(jù)庫(kù)中新建Metadata表,并把Migrations應(yīng)用到該數(shù)據(jù)庫(kù)。

Baseline可以應(yīng)用到特定的版本,這樣在已有表結(jié)構(gòu)的數(shù)據(jù)庫(kù)中也可以實(shí)現(xiàn)添加Metadata表,從而利用Flyway進(jìn)行新Migrations的管理了。
Repair
Repair操作能夠修復(fù)Metadata表,該操作在Metadata表出現(xiàn)錯(cuò)誤時(shí)是非常有用的。

Repair會(huì)修復(fù)Metadata表的錯(cuò)誤,通常有兩種用途:
- 移除失敗的Migration記錄,該問題只是針對(duì)不支持DDL事務(wù)的數(shù)據(jù)庫(kù)。
- 重新調(diào)整已經(jīng)應(yīng)用的Migratons的Checksums值,比如:某個(gè)Migratinon已經(jīng)被應(yīng)用,但本地進(jìn)行了修改,又期望重新應(yīng)用并調(diào)整Checksum值,不過盡量不要這樣操作,否則可能造成其它環(huán)境失敗。
如何使用Flyway?
這里將主要關(guān)注在Gradle和Spring Boot中集成并使用Flyway,數(shù)據(jù)庫(kù)通常會(huì)采用MySQL、PostgreSQL、H2或Hsql等。
正確創(chuàng)建Migrations
Migrations是指Flyway在更新數(shù)據(jù)庫(kù)時(shí)是使用的版本腳本,比如:一個(gè)基于Sql的Migration命名為V1__init_tables.sql,內(nèi)容即是創(chuàng)建所有表的sql語(yǔ)句,另外,F(xiàn)lyway也支持基于Java的Migration。Flyway加載Migrations的默認(rèn)Locations為classpath:db/migration,也可以指定filesystem:/project/folder,其加載是在Runtime自動(dòng)遞歸地執(zhí)行的。

除了需要指定Location外,F(xiàn)lyway對(duì)Migrations的掃描還必須遵從一定的命名模式,Migration主要分為兩類:Versioned和Repeatable。
Versioned migrations
一般常用的是Versioned類型,用于版本升級(jí),每一個(gè)版本都有一個(gè)唯一的標(biāo)識(shí)并且只能被應(yīng)用一次,并且不能再修改已經(jīng)加載過的Migrations,因?yàn)镸etadata表會(huì)記錄其Checksum值。其中的version標(biāo)識(shí)版本號(hào),由一個(gè)或多個(gè)數(shù)字構(gòu)成,數(shù)字之間的分隔符可以采用點(diǎn)或下劃線,在運(yùn)行時(shí)下劃線其實(shí)也是被替換成點(diǎn)了,每一部分的前導(dǎo)零會(huì)被自動(dòng)忽略。
Repeatable migrations
Repeatable是指可重復(fù)加載的Migrations,其每一次的更新會(huì)影響Checksum值,然后都會(huì)被重新加載,并不用于版本升級(jí)。對(duì)于管理不穩(wěn)定的數(shù)據(jù)庫(kù)對(duì)象的更新時(shí)非常有用。Repeatable的Migrations總是在Versioned之后按順序執(zhí)行,但開發(fā)者必須自己維護(hù)腳本并且確??梢灾貜?fù)執(zhí)行,通常會(huì)在sql語(yǔ)句中使用CREATE OR REPLACE來保證可重復(fù)執(zhí)行。
默認(rèn)情況下基于Sql的Migration文件的命令規(guī)則如下圖所示:

其中的文件名由以下部分組成,除了使用默認(rèn)配置外,某些部分還可自定義規(guī)則。
- prefix: 可配置,前綴標(biāo)識(shí),默認(rèn)值V表示Versioned,R表示Repeatable
- version: 標(biāo)識(shí)版本號(hào),由一個(gè)或多個(gè)數(shù)字構(gòu)成,數(shù)字之間的分隔符可用點(diǎn).或下劃線_
- separator: 可配置,用于分隔版本標(biāo)識(shí)與描述信息,默認(rèn)為兩個(gè)下劃線__
- description: 描述信息,文字之間可以用下劃線或空格分隔
- suffix: 可配置,后續(xù)標(biāo)識(shí),默認(rèn)為.sql
另外,關(guān)于如何使用基于Java的Migrations,有興趣可以參考Java-based migrations。
支持的數(shù)據(jù)庫(kù)
目前Flyway支持的數(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 Phoenix。
目前來說,個(gè)人用得比較多的數(shù)據(jù)庫(kù)是PostgreSQL、MySQL、H2和Hsql,針對(duì)每種數(shù)據(jù)庫(kù)的flyway.url示例配置為:
另外,關(guān)于如何使用基于Java的Migrations,有興趣可以參考Java-based migrations。
支持的數(shù)據(jù)庫(kù)
目前Flyway支持的數(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 Phoenix。
目前來說,個(gè)人用得比較多的數(shù)據(jù)庫(kù)是PostgreSQL、MySQL、H2和Hsql,針對(duì)每種數(shù)據(jù)庫(kù)的flyway.url示例配置為:
# PostgreSQL flyway.url = jdbc:postgresql://localhost:5432/postgres?currentSchema=myschema # MySQL flyway.url = jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC&useSSL=true # H2 flyway.url = jdbc:h2:./.tmp/testdb # Hsql flyway.url = jdbc:hsqldb:hsql//localhost:1476/testdb
Flyway命令行
Flyway的命令行工具支持直接在命令行中運(yùn)行Migrate,Clean,Info,Validate,Baseline和Repair6種命令,不需要借助其他Build工具,不需要應(yīng)用程序運(yùn)行在JVM中,只需要單純的命令行即可,但需要根據(jù)不同的操作系統(tǒng)下載并安裝該命令行工具。Flyway會(huì)依次搜索以下配置文件,越靠后的配置會(huì)覆蓋靠前的配置:
- /conf/flyway.conf
- /flyway.conf
- /flyway.conf
一個(gè)典型Flyway項(xiàng)目示例目錄結(jié)構(gòu)如下:

更多關(guān)于Flyway命令行使用可以參考Flyway Command-line。
在Gradle中的應(yīng)用
首先需要在Gradle中引入Flyway插件,通常有兩種方式:
方式一:采用buildscript依賴方式。
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.flywaydb:flyway-gradle-plugin:4.0.3")
}
}
apply plugin: 'org.flywaydb.flyway'
方式二(推薦):采用DSL方式引用Plugins。
plugins {
id "org.flywaydb.flyway" version "4.0.3"
}
而在Gradle中配置Flyway Properties有兩種方式:
方式一:在build.gradle中配置Flyway Properties。
flyway {
url = jdbc:h2:./.tmp/testdb
user = sa
password =
}
# 或者寫成:
project.ext['flyway.url'] = 'jdbc:h2:./.tmp/testdb'
project.ext['flyway.user'] = 'sa'
project.ext['flyway.password'] = ''
方式二:在gradle.properties中配置Flyway Properties。
flyway.url = jdbc:h2:./.tmp/testdb flyway.user = sa flyway.password =
如果期望在運(yùn)行Gradle Clean/Build Tasks時(shí)自動(dòng)執(zhí)行Flyway的某些任務(wù),可以設(shè)置dependsOn,若不期望隱式執(zhí)行Flyway任務(wù),可以不配置。
clean.dependsOn flywayRepair # To repair the Flyway metadata table build.dependsOn flywayMigrate # To migrate the schema to the latest version
另外,其它Tasks:flywayInfo,flywayValidate,flywayBaseline分別對(duì)應(yīng)到Flyway的命令。在使用Spring Boot時(shí),運(yùn)行./gradlew bootRun會(huì)自動(dòng)檢查并加載最新的db.migration腳本。
特別注意:在Production環(huán)境中不應(yīng)執(zhí)行./gradlew flywayClean,除非你知道自己的行為和目的,因?yàn)樵撁顣?huì)清除所有的數(shù)據(jù)庫(kù)對(duì)象,相當(dāng)危險(xiǎn)。
更多關(guān)于Flyway在Gradle中的使用請(qǐng)參閱Flyway Gradle Plugin。
與Spring Boot集成
在Spring Boot中,如果加入Flyway的依賴,則會(huì)自動(dòng)引用Flyway并使用默認(rèn)值,但可以修改并配置FlywayProperties。
flyway.baseline-description= # The description to tag an existing schema with when executing baseline. flyway.baseline-version=1 # Version to start migration. flyway.baseline-on-migrate=false # Whether to execute migration against a non-empty schema with no metadata table flyway.check-location=false # Check that migration scripts location exists. flyway.clean-on-validation-error=false # will clean all objects. Warning! Do NOT enable in production! flyway.enabled=true # Enable flyway. flyway.encoding=UTF-8 # The encoding of migrations. flyway.ignore-failed-future-migration=true # Ignore future migrations when reading the metadata table. flyway.init-sqls= # SQL statements to execute to initialize a connection immediately after obtaining it. flyway.locations=classpath:db/migration # locations of migrations scripts. flyway.out-of-order=false # Allows migrations to be run "out of order". flyway.placeholder-prefix= # The prefix of every placeholder. flyway.placeholder-replacement=true # Whether placeholders should be replaced. flyway.placeholder-suffix=} # The suffix of every placeholder. flyway.placeholders.*= # Placeholders to replace in Sql migrations. flyway.schemas= # Default schema of the connection and updating flyway.sql-migration-prefix=V # The file name prefix for Sql migrations flyway.sql-migration-separator=__ # The file name separator for Sql migrations flyway.sql-migration-suffix=.sql # The file name suffix for Sql migrations flyway.table=schema_version # The name of Flyway's metadata table. flyway.url= # JDBC url of the database to migrate. If not set, the primary configured data source is used. flyway.user= # Login user of the database to migrate. If not set, use spring.datasource.username value. flyway.password= # JDBC password if you want Flyway to create its own DataSource. flyway.validate-on-migrate=true # Validate sql migration CRC32 checksum in classpath.
若使用Gradle,通常在build.gradle引入org.flywaydb:flyway-core:4.0.3依賴后即可使用??赡軙?huì)有以下幾種需求:
- 在本地Run和Tests都會(huì)使用內(nèi)存數(shù)據(jù)庫(kù),其中的
spring.jpa.hibernate.ddl-auto都設(shè)置為validate,Schema不需要Hibernate自動(dòng)生成,并期望使用Flyway,而在線上環(huán)境會(huì)使用真實(shí)數(shù)據(jù)庫(kù),并不期望使用Flyway,如何實(shí)現(xiàn)呢? - 解決方案:可以在
common.properties中配置flyway.enabled=false,然后在local或dev的配置中啟用Flyway即可。通常推薦使用此模式,畢竟可以對(duì)不同的環(huán)境進(jìn)行控制,另外本地Run不會(huì)依賴真實(shí)數(shù)據(jù)庫(kù),又能保證數(shù)據(jù)庫(kù)Schema是按腳本創(chuàng)建的。 - 在運(yùn)行Tests會(huì)使用內(nèi)存數(shù)據(jù)庫(kù),有單獨(dú)的配置文件,不使用Flyway,而在本地bootRun時(shí)會(huì)使用真實(shí)數(shù)據(jù)庫(kù),使用Flyway,畢竟不想每次Schema改后都在本地手動(dòng)去執(zhí)行腳本,如何實(shí)現(xiàn)?
解決方案:設(shè)置bootRun.dependsOn動(dòng)態(tài)添加Flyway的依賴即可:
addFlywayDenpendency {
doLast {
dependencies {
compile('org.flywaydb:flyway-core:4.0.3')
}
}
}
bootRun.dependsOn=addFlywayDenpendency
若項(xiàng)目有多個(gè)團(tuán)隊(duì)同時(shí)開發(fā)不同的功能,需要新建多個(gè)分支,并且都會(huì)涉及到數(shù)據(jù)庫(kù)Schema更改,當(dāng)后期Merge時(shí),Migration的版本如何控制并且不會(huì)產(chǎn)生數(shù)據(jù)庫(kù)更改的沖突呢?
解決方案:如果兩個(gè)分支的數(shù)據(jù)庫(kù)更改有沖突,要么最初數(shù)據(jù)庫(kù)設(shè)計(jì)不合理,要么目前數(shù)據(jù)庫(kù)更改不合理,所以需要團(tuán)隊(duì)進(jìn)行全局考慮和協(xié)調(diào)。而針對(duì)數(shù)據(jù)庫(kù)在同一段時(shí)間有修改,但不會(huì)造成沖突的情況,通常實(shí)際項(xiàng)目中主要存在這樣的情況,那可以設(shè)置flyway.out-of-order=true,這樣允許當(dāng)v1和v3已經(jīng)被應(yīng)用后,v2出現(xiàn)時(shí)同樣也可以被應(yīng)用。其實(shí)在本地使用內(nèi)存數(shù)據(jù)庫(kù)不會(huì)存在該問題,因?yàn)閿?shù)據(jù)庫(kù)所有對(duì)象會(huì)自動(dòng)清除掉,而在local或dev中使用真實(shí)數(shù)據(jù)庫(kù)時(shí)可遇到這樣的問題,因此需要注意一下了。
另外,值得一提的是Flyway的參數(shù)ignore-failed-future-migration默認(rèn)為true,使用情形為:當(dāng)Rollback數(shù)據(jù)庫(kù)更改到舊版本,而metadata表中已存在了新版本時(shí),F(xiàn)lyway會(huì)忽略此錯(cuò)誤,只會(huì)顯示警告信息。
結(jié)束語(yǔ)
總得來說,F(xiàn)lyway可以有效改善數(shù)據(jù)庫(kù)版本管理方式,如果項(xiàng)目中還未使用,不防嘗試一下。如果有興趣,也可以關(guān)注MyBatis Migration,功能支持沒有Flyway多,屬于更輕量級(jí)的數(shù)據(jù)庫(kù)版本管理工具。如果在使用過程中遇到了問題或坑,歡迎留言一起交流討論。
References
Spring Common application properties
Execute Flyway database migrations on startup
到此這篇關(guān)于快速掌握和使用Flyway的詳細(xì)教程的文章就介紹到這了,更多相關(guān)使用Flyway的技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
git分支(branch)操作相關(guān)命令及分支命令的使用
這篇文章主要介紹了git分支(branch)操作相關(guān)命令及分支命令的使用的相關(guān)資料,需要的朋友可以參考下2017-10-10
SonarQube實(shí)現(xiàn)自動(dòng)化代碼掃描的安裝及使用集成方式
Sonar是一個(gè)用于代碼質(zhì)量管理的開源平臺(tái),通過插件機(jī)制,Sonar可與第三方工具進(jìn)行集成。將Sonar引入到代碼開發(fā)的過程中,提供靜態(tài)源代碼安全掃描能力,這無疑是安全左移的一次很好的嘗試和探索2021-10-10
gaussdb 200安裝 data studio jdbc idea鏈接保姆級(jí)安裝步驟
這篇文章主要介紹了gaussdb 200安裝 data studio jdbc idea鏈接保姆級(jí)安裝步驟,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
使用git處理github中提交有沖突的pull request的問題
這篇文章主要介紹了使用git處理github中提交有沖突的pull request,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
minio對(duì)象存儲(chǔ)四臺(tái)服務(wù)器部署4個(gè)節(jié)點(diǎn)集群的實(shí)現(xiàn)方式
這篇文章主要介紹了minio對(duì)象存儲(chǔ)四臺(tái)服務(wù)器部署4個(gè)節(jié)點(diǎn)集群,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
Web 開發(fā)中遇到的UTF-8編碼的問題總結(jié)
一個(gè)網(wǎng)站如果需要國(guó)際化,就需要將編碼從GB2312轉(zhuǎn)成UTF-8,其中有很多的問題需要注意,如果沒有轉(zhuǎn)換徹底,將會(huì)有很多的編碼問題出現(xiàn)!2010-02-02
關(guān)于IDEA git 只有Commit沒有Push的問題
這篇文章主要介紹了關(guān)于IDEA git 只有Commit沒有Push的問題,本文給大家介紹的非常想詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

