Fork me on GitHub

自定义开发数据库升级程序

原始诉求

很多时候,我们在进行程序版本开发中,会遇到数据库升级的情况,为了避免提供给运维人员额外的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());
        }    

}

 

posted @ 2022-01-06 22:40  糖拌西红柿  阅读(459)  评论(2编辑  收藏  举报