自定義開發資料庫升級程式

糖拌蕃茄發表於2022-01-06

原始訴求

很多時候,我們在進行程式版本開發中,會遇到資料庫升級的情況,為了避擴音供給運維人員額外的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());
        }    

}

 

相關文章