自定義開發數據庫升級程序


原始訴求

很多時候,我們在進行程序版本開發中,會遇到數據庫升級的情況,為了避免提供給運維人員額外的sql文件去執行,最好是由程序本身去完成該部分的任務(畢竟人為的事情不可控因素較多,因為人為升級數據庫造成的混亂、加班慘不忍睹……);最終的目標就是,將數據庫的變動全部變為sql,由本身的程序包(jar,war等)攜帶,在替換包的時候,數據庫會保證最新狀態。

程序結構設計

這里,我采用java進行設計,整體的設計圖如下:

 

各個類的作用:

InitDataBase(接口):定義初始化所需功能
ExcuteActuator(接口):配置執行器,主要定義輔助升級過程中各類配置的獲取功能
AbstractInitDataBase(抽象類):實現了 InitDataBase和ExcuteActuator接口,是所有具體升級類的父類,指定了核心的數據庫升級步驟,完成了ExcuteActuator接口的大部分配置功能
MySqlDataBase(具體實現類):具體針對mysql數據庫進行升級的初始化類

這里完成了整個程序的架子,目前僅實現了mysql的自動升級,后續有興趣,可以自動擴充Oracle等其他數據庫的升級過程,只需要繼承AbstractInitDataBase類,完成InitDataBase定義的功能即可。

github:https://github.com/GCC1566/Conscript

核心代碼

public interface InitDataBase {


    /**
     * 數據庫初始化條件是否完成
     * @return boolean
     */
    boolean isInitEd();

    /**
     * 核心任務
     * 1、建立鏈接
     * 2、是否可鏈接
     * 3、是否存在庫
     * 4、版本是否需要升級
     */
    void startCoreJob() throws SQLException;

    /**
     * 建立鏈接
     * @return boolean
     */
    boolean createConnection();

    /**
     * 確認庫是否存在
     * @return boolean
     */
    boolean databaseIsExitd() throws SQLException;

    /**
     * 獲取當前數據庫版本
     * @return
     */
    Float getCurrenDbVersion() throws SQLException;

    /**
     * 執行sql內容
     * @param sqlcontent
     * @return
     * @throws SQLDataException
     */
    boolean excuteSQL(Map<String, String> sqlcontent) throws SQLDataException;

    /**
     * 關閉連接
     * @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("【數據庫初始化】開始基本數據庫初始化");
        if(createConnection()){
            log.info("【數據庫初始化】成功建立與數據庫的聯系");
            Map<String,String> sqlcontent;
            if(databaseIsExitd()) {
                //比對代碼配置中所需數據庫版本是否大於當前數據庫中實際版本
                if(getLatestVersion() > getCurrenDbVersion()) {
                    log.info("【數據庫初始化】當前數據庫版本較低,進行數據庫升級");
                    sqlcontent = getSqlFromFile(getCurrenDbVersion());
                }else {
                    log.info("【數據庫初始化】當前數據庫已是最新版本");
                    flag = true;
                    return;
                }
            }else{
                log.info("【數據庫初始化】檢驗到本系統所需數據庫不存在,開啟自動建庫流程");
                sqlcontent = getSqlFromFile(0f);
            }
            flag = excuteSQL(sqlcontent);
        }else{
            log.error("【數據庫初始化】與數據庫服務建立鏈接失敗 ! 請確認數據庫服務是否正常或配置是否正確!");
        }
        close();
    }

}

使用方式

引入Conscript

1.使用依賴引入

<dependency>
    <groupId>com.gcc</groupId>
    <artifactId>Conscript</artifactId>
    <version>1.0</version>
</dependency>

 由於暫未正式發布,該方式僅限於本地編譯代碼后發布至本地私倉

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": "基礎數據庫結構"
   },
    {
       "version": "1.1",
       "sqlfile": "ddd.sql",
       "desc": "第一版升級數據庫"
    }
 ]

 

參數 意義
host 數據庫服務ip地址
port 數據庫服務端口
dbname 數據庫名稱(需要初始化的庫名)
user 數據庫連接賬號
password 數據庫連接密碼
dbconfigfileurl 數據庫升級配置文件
driverclassname 數據庫連接驅動名稱
dbtype 數據庫類型

使用初始器工廠創建數據庫初始器

將DbConConfiguration對象作為DataBaseInitorFactory工廠方法的參數,生產數據庫初始器對象,進行數據庫初始化:

 

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("數據庫錯誤"+e.getMessage());
        }    

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM