自定義開發(fā)數(shù)據(jù)庫升級程序
原始訴求
很多時候,我們在進(jìn)行程序版本開發(fā)中,會遇到數(shù)據(jù)庫升級的情況,為了避免提供給運(yùn)維人員額外的sql文件去執(zhí)行,最好是由程序本身去完成該部分的任務(wù)(畢竟人為的事情不可控因素較多,因為人為升級數(shù)據(jù)庫造成的混亂、加班慘不忍睹……);最終的目標(biāo)就是,將數(shù)據(jù)庫的變動全部變?yōu)閟ql,由本身的程序包(jar,war等)攜帶,在替換包的時候,數(shù)據(jù)庫會保證最新狀態(tài)。
程序結(jié)構(gòu)設(shè)計
這里,我采用java進(jìn)行設(shè)計,整體的設(shè)計圖如下:

各個類的作用:
InitDataBase(接口):定義初始化所需功能
ExcuteActuator(接口):配置執(zhí)行器,主要定義輔助升級過程中各類配置的獲取功能
AbstractInitDataBase(抽象類):實(shí)現(xiàn)了 InitDataBase和ExcuteActuator接口,是所有具體升級類的父類,指定了核心的數(shù)據(jù)庫升級步驟,完成了ExcuteActuator接口的大部分配置功能
MySqlDataBase(具體實(shí)現(xiàn)類):具體針對mysql數(shù)據(jù)庫進(jìn)行升級的初始化類
這里完成了整個程序的架子,目前僅實(shí)現(xiàn)了mysql的自動升級,后續(xù)有興趣,可以自動擴(kuò)充Oracle等其他數(shù)據(jù)庫的升級過程,只需要繼承AbstractInitDataBase類,完成InitDataBase定義的功能即可。
github:https://github.com/GCC1566/Conscript
核心代碼
public interface InitDataBase { /** * 數(shù)據(jù)庫初始化條件是否完成 * @return boolean */ boolean isInitEd(); /** * 核心任務(wù) * 1、建立鏈接 * 2、是否可鏈接 * 3、是否存在庫 * 4、版本是否需要升級 */ void startCoreJob() throws SQLException; /** * 建立鏈接 * @return boolean */ boolean createConnection(); /** * 確認(rèn)庫是否存在 * @return boolean */ boolean databaseIsExitd() throws SQLException; /** * 獲取當(dāng)前數(shù)據(jù)庫版本 * @return */ Float getCurrenDbVersion() throws SQLException; /** * 執(zhí)行sql內(nèi)容 * @param sqlcontent * @return * @throws SQLDataException */ boolean excuteSQL(Map<String, String> sqlcontent) throws SQLDataException; /** * 關(guān)閉連接 * @return */ void close() throws SQLException; }
public abstract class AbstractInitDataBase implements InitDataBase { String DB_CONFIG_URL; public JSONArray dbconfig = new JSONArray(); public DbConConfiguration dbConConfiguration; public static Boolean flag = false; public AbstractInitDataBase(DbConConfiguration conConfiguration){ DB_CONFIG_URL = conConfiguration.getDbconfigfileurl(); dbConConfiguration = conConfiguration; } @Override public boolean isInitEd() { return flag; } @Override public void startCoreJob() throws SQLException { reloadConfigFile(); log.info("【數(shù)據(jù)庫初始化】開始基本數(shù)據(jù)庫初始化"); if(createConnection()){ log.info("【數(shù)據(jù)庫初始化】成功建立與數(shù)據(jù)庫的聯(lián)系"); Map<String,String> sqlcontent; if(databaseIsExitd()) { //比對代碼配置中所需數(shù)據(jù)庫版本是否大于當(dāng)前數(shù)據(jù)庫中實(shí)際版本 if(getLatestVersion() > getCurrenDbVersion()) { log.info("【數(shù)據(jù)庫初始化】當(dāng)前數(shù)據(jù)庫版本較低,進(jìn)行數(shù)據(jù)庫升級"); sqlcontent = getSqlFromFile(getCurrenDbVersion()); }else { log.info("【數(shù)據(jù)庫初始化】當(dāng)前數(shù)據(jù)庫已是最新版本"); flag = true; return; } }else{ log.info("【數(shù)據(jù)庫初始化】檢驗到本系統(tǒng)所需數(shù)據(jù)庫不存在,開啟自動建庫流程"); sqlcontent = getSqlFromFile(0f); } flag = excuteSQL(sqlcontent); }else{ log.error("【數(shù)據(jù)庫初始化】與數(shù)據(jù)庫服務(wù)建立鏈接失敗 ! 請確認(rèn)數(shù)據(jù)庫服務(wù)是否正常或配置是否正確!"); } close(); } }
使用方式
引入Conscript
1.使用依賴引入
<dependency> <groupId>com.gcc</groupId> <artifactId>Conscript</artifactId> <version>1.0</version> </dependency>
由于暫未正式發(fā)布,該方式僅限于本地編譯代碼后發(fā)布至本地私倉
2.直接引入代碼
可在github上引用源碼,將com.gcc.initdb目錄下的initdb包拷至代碼中即可
3.使用jar包
將打包后的jar包引入項目,具體jar包留言私信即可
建立SQL文件存放目錄
1.在resource目錄下新建sql目錄,里面存放需要升級的sql文件
2.在resource目錄下新建XX.json文件作為配置文件,XX.json文件樣例如下:
mysql-dbconfig.json
[ { "version": "1.0", "sqlfile": "a.sql", "desc": "基礎(chǔ)數(shù)據(jù)庫結(jié)構(gòu)" }, { "version": "1.1", "sqlfile": "ddd.sql", "desc": "第一版升級數(shù)據(jù)庫" } ]
| 意義 | |
|---|---|
| host | 數(shù)據(jù)庫服務(wù)ip地址 |
| port | 數(shù)據(jù)庫服務(wù)端口 |
| dbname | 數(shù)據(jù)庫名稱(需要初始化的庫名) |
| user | 數(shù)據(jù)庫連接賬號 |
| password | 數(shù)據(jù)庫連接密碼 |
| dbconfigfileurl | 數(shù)據(jù)庫升級配置文件 |
| driverclassname | 數(shù)據(jù)庫連接驅(qū)動名稱 |
| dbtype |
使用初始器工廠創(chuàng)建數(shù)據(jù)庫初始器
將DbConConfiguration對象作為DataBaseInitorFactory工廠方法的參數(shù),生產(chǎn)數(shù)據(jù)庫初始器對象,進(jìn)行數(shù)據(jù)庫初始化:
public static void main(String args[]){ DbConConfiguration conConfiguration = new DbConConfiguration.Builder() .setHost(cfgBean.getHost()) .setDbport(cfgBean.getDbport()) .setDbname(cfgBean.getDbname()) .setConfigFileUrl("mysql-dbconfig.json") .setDriverclassname(cfgBean.getDriverclassname()) .setDbtype(cfgBean.getDbtype().getDbtype()) .setUser(cfgBean.getUser()) .setPassword(cfgBean.getPassword()) .build(); InitDataBase initdb = DataBaseInitorFactory.createInitiator(conConfiguration); try { initdb.startCoreJob(); }catch (SQLException e){ log.error("數(shù)據(jù)庫錯誤"+e.getMessage()); } }

浙公網(wǎng)安備 33010602011771號