在项目开发初级阶段,由于设计的不完善,经常需要对数据库进行修改。甚至到了项目的中后期,依然需要修改数据库设计来配合业务上的某些重要变动。直接操作数据库或者使用工具,使用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,后期可自己扩展实现 |
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,有需要的同学可看看。点击打开链接