使用监听器实现数据库版本增量更新

        在项目开发初级阶段,由于设计的不完善,经常需要对数据库进行修改。甚至到了项目的中后期,依然需要修改数据库设计来配合业务上的某些重要变动。直接操作数据库或者使用工具,使用sql脚本对数据库进行改动方便直接。但本人认为,对于整个项目的变更,从数据库方面来看并不是很直接明了。本demo实现的是,项目需要维护一个t_system_info的表用于记录系统的一些基本信息,包括当前数据库的版本。在系统启动的时候,先去读取这张表获取当前的版本号,再到项目指定的文件夹中寻找是否有新的版本,如果有,执行更新语句或者更新文件。为了方便演示,demo使用springboot搭建,项目流程和项目结构如下图所示。

使用监听器实现数据库版本增量更新_第1张图片

        如上图,在资源文件夹resource中创建用于存放升级文件的文件夹upgrade,升级文件及升级版本号存放在UpgradeConfigFile.json文件中,upgrade/mysql/file存放的是升级所需的sql脚本,upgrade/mysql/proc存放的是存储过程的升级文件。pojo存放的是json转对象所需的类,listener存放监听器文件,init存放操作升级所需的类。其中DatabaseContext用于创建数据库连接和关闭连接;DatabasePatchService用于判断当前数据库版本,以及是否有升级等;UpdateTask主要用于执行升级。

需要维护的t_system_info表,可以根据需要进行改动,建表语句如下:

DROP TABLE IF EXISTS `t_system_info`;
CREATE TABLE `t_system_info` (
  `id` varchar(32) NOT NULL COMMENT '主键id',
  `parent_id` varchar(32) DEFAULT NULL COMMENT '父id',
  `param` varchar(255) DEFAULT NULL COMMENT '参数',
  `param_name` varchar(255) DEFAULT NULL COMMENT '参数名称',
  `param_value` varchar(32) DEFAULT NULL COMMENT '参数值',
  `py_code` varchar(255) DEFAULT NULL COMMENT '拼音',
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `ip_address` varchar(255) DEFAULT NULL COMMENT 'ip地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统参数表';

INSERT INTO `t_system_info` (`id`, `parent_id`, `param`, `param_name`, `param_value`, `py_code`, `update_time`, `ip_address`) VALUES (REPLACE(UUID(),'-',''), NULL, 'DBVersion', '数据库版本号', '1.00', 'SJKBBH', now(), '127.0.0.1');


UpgradeConfigFile.json文件如下:

{
  "isUpdateDbVersion":"true",
  "tableName":"t_system_info",
  "fieldName":"param_value",
  "queryWhere":"param='DBVersion'",
  "updateItem":[
    {
      "version":"1.01",
      "updateBody":[
        {
          "type":"SqlFile",
          "dbType":"Mysql",
          "text":"/mysql/file/create_table_t_user_20180326.sql",
          "desc":"创建t_user表"
        },
        {
          "type":"SqlStatement",
          "dbType":"Mysql",
          "text":"INSERT INTO `t_user` (`id`, `username`, `password`) VALUES (REPLACE(UUID(),'-',''), 'admin', '123456');",
          "desc":"插入一条user数据"
        }
      ]
    },
    {
      "version":"1.02",
      "updateBody":[
        {
          "type":"SqlStatement",
          "dbType":"Mysql",
          "text":"CREATE VIEW test AS  (SELECT * from  t_system_info);",
          "desc":"创建视图"
        }
      ]
    }
  ]
}

isUpdateDbVersion 是否为升级文件
tableName 版本号存放的表
fieldName 版本号对应的列名
queryWhere 查询或者更新版本号所需的条件
updateItem 所有的更新内容
version 版本号
updateBody 该版本所需更新的内容
type 更新类型,SqlFile表示通过读取sql脚本更新,SqlStatement表示通过sql语句更新
dbType 目前仅有Mysql,后期可自己扩展实现
text sql更新文件路径,或者为sql更新语句
desc 无具体意义,只是为了描述本更新

本demo使用springboot 1.5.5.RELEASE 搭建,其他jar的依赖如下:


	com.alibaba
	fastjson
	1.2.46



	commons-io
	commons-io
	2.6



	org.apache.commons
	commons-lang3
	3.7

在 BeforeStartListener 需要加上 @WebListener注解


在Springboot启动类上加上@ServletComponentScan注解


具体操作都在UpdateTask这个类中,该demo已上传至GitHub,有需要的同学可看看。点击打开链接



你可能感兴趣的:(SpringBoot)