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