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

本文介绍了一种基于Spring Boot的应用程序中实现数据库自动升级的方法。通过维护一张包含数据库版本信息的表,并结合JSON配置文件与SQL脚本来实现版本检查与自动升级。此方案适用于频繁更新数据库结构的场景。

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


        如上图,在资源文件夹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,后期可自己扩展实现
textsql更新文件路径,或者为sql更新语句
desc无具体意义,只是为了描述本更新

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

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.46</version>
</dependency>

<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.6</version>
</dependency>

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.7</version>
</dependency>

在 BeforeStartListener 需要加上 @WebListener注解


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


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



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值