XX出行项目子系统-统计系统设计(定时器项目设计例子)

一. 引言

  目前开发的XX出行系统,需要开发数据统计功能,鉴于约约出行系统已经在运营,并且有新版本的迭代,方便以后下个版本复用,遂新建一个子系统。

二. 架构设计

  

三. 具体实现

   1.MySql数据库

  (1)配置表:使用配置表,控制要执行的存储过程。

CREATE TABLE `t_report_config` (  
  `uuid` varchar(32) NOT NULL COMMENT '主键ID',  
  `source_view` varchar(64) NOT NULL COMMENT '数据源视图',  
  `result_table` varchar(64) NOT NULL COMMENT '结果存储表',  
  `cycle` int(11) NOT NULL COMMENT '周期类型(1:小时,2:天)',  
  `status` int(11) DEFAULT NULL COMMENT '状态(0:失败,1:成功)',  
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',  
  PRIMARY KEY (`uuid`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='统计报表_配置表';

  (2)存储过程:存储过程根据配置表给的视图名和存储表,将视图的数据存储到存储表中。

CREATE DEFINER=`admin`@`%` PROCEDURE `P_REPORT_CONFIG`(IN args_cycle INT)  
BEGIN  
    -- 需要定义接收游标数据的变量  
  
-- 配置表主键ID  
DECLARE var_uuid CHAR (32);  
  
-- 数据源视图  
DECLARE var_source_view CHAR (64);  
  
-- 结果存储表  
DECLARE var_result_table CHAR (64);  
  
-- 周期类型(1:小时,2:天)  
DECLARE var_cycle INT;  
  
-- 状态(0:失败,1:成功)  
DECLARE var_status INT;  
  
-- 动态SQL语句  
DECLARE sqlStr VARCHAR(500);  
  
  
-- 遍历数据结束标志  
DECLARE done INT DEFAULT FALSE;  
  
-- 游标  
DECLARE cur CURSOR FOR SELECT  
    trc.uuid var_uuid,  
    trc.source_view var_source_view,  
    trc.result_table var_result_table,  
    trc.cycle var_cycle,  
    trc.status var_status  
    FROM  
    t_report_config trc WHERE trc.cycle = args_cycle  
;  
  
-- 将结束标志绑定到游标  
DECLARE CONTINUE HANDLER FOR NOT FOUND  
SET done = TRUE;  
  
-- 打开游标  
OPEN cur;  
  
-- 开始循环  
read_loop :  
LOOP  
    -- 提取游标里的数据,这里只有一个,多个的话也一样;  
    FETCH cur INTO  
    var_uuid,  
    var_source_view,  
    var_result_table,  
    var_cycle,  
    var_status;  
  
-- 声明结束的时候  
IF done THEN  
    LEAVE read_loop;  
  
  
END  
IF;  
  
-- 这里做你想做的循环的事件  
  
SET @tableName = var_result_table;  
SET @viewName = var_source_view;  
set sqlStr = CONCAT('INSERT INTO ',@tableName,' SELECT * FROM ',@viewName);  
SET @sqlstr = sqlStr;  
PREPARE stmt from @sqlstr;  
EXECUTE stmt;  
deallocate prepare stmt;  
  
  
UPDATE t_report_config trc SET trc.`status` = 1,trc.update_time = NOW() WHERE trc.uuid = var_uuid;  
  
END  
LOOP  
;  
  
-- 关闭游标  
CLOSE cur;  
  
  
END

  (3)视图(略):查询的SQL,放到新建视图就可以生成。假设存储过程的入参是1,那么就使用所有配置表中cycle=1的记录,每小时统计一次。

  (4)远程表连接:FEDERATED:FEDERATED存储引擎是访问远程数据库中的表,在平时开发中可以用此特性来访问远程库中的参数表之类的,还是非常方便的。使用时直接在本地构建一个federated表来链接远程数据表,配置好之后本地数据库可以直接和远程数据表进行同步,实际上这个数据库并不是真实存放数据,所需要的数据都是存放在远程服务器上。配置条件:mysql版本需要5.1以上;在安装是需要把federated引擎已经安装;检查是否开启:show engines;如果没开启,则:修改mysql的配置文件,在my.ini中[mysqld]标签下下直接加上一行 federated重启数据库服务即可。建立远程表连接:ENGINE=FEDERATED DEFAULT CHARSET=utf8 COMMENT='订单表' CONNECTION='mysql://user:password@ip:port/schema/tableName';

CREATE TABLE `yy_order` (  
  `uuid` char(32) NOT NULL,  
  `order_no` varchar(32) DEFAULT NULL COMMENT '订单号',  
  PRIMARY KEY (`uuid`),  
) ENGINE=FEDERATED DEFAULT CHARSET=utf8 COMMENT='订单表' CONNECTION='mysql://user:password@ip:port/schema/tableName';

  2.Java工程方面

  (1)定时器类:

package com.summersoft.ts.base;  
  
import com.summersoft.ts.service.ConfigService;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
@Component("processTask")  
public class ProcessTask {  
  
    @Autowired  
    private ConfigService configService;  
  
    /** 
     * 执行存储过程(小时) 
     */  
    public void  runHourProcess(){  
        configService.processReportConfig(1);  
    }  
  
    /** 
     * 执行存储过程(天) 
     */  
    public void  runDayProcess(){  
        configService.processReportConfig(2);  
    }  
}  

  (2)定时器配置:applicationContext.xml里面<beans></beans>添加配置
  

<!-- 定时任务配置 -->  
<task:scheduled-tasks>  
    <task:scheduled ref="processTask" method="runHourProcess" cron="0 0 * * * *" />  
    <task:scheduled ref="processTask" method="runDayProcess" cron="0 0 3 * * *" />  
</task:scheduled-tasks> 

  (3) ConfigService:

package com.summersoft.ts.service;  
  
public interface ConfigService {  
    void processReportConfig(int cycle);  
}

  (4)ConfigServiceImpl:

package com.summersoft.ts.service.impl;  
  
import com.summersoft.ts.dao.ReportConfigDao;  
import com.summersoft.ts.service.ConfigService;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  
  
@Service("configService")  
public class ConfigServiceImpl implements ConfigService {  
  
    @Autowired  
    private ReportConfigDao configDao;  
  
    @Override  
    public void processReportConfig(int cycle) {  
        try {  
            configDao.processReportConfig(cycle);  
        }catch (Exception e){  
            System.out.println("存储过程执行异常:"+e.getMessage());  
        }  
    }  
} 

  (5)ReportConfigMapper.xml对应的SQL写法:

<select id="processReportConfig" statementType="CALLABLE" parameterType="int">  
    {CALL P_REPORT_CONFIG(#{cycle, mode=IN, jdbcType=INTEGER})}  
</select> 

  

原文地址:https://www.cnblogs.com/knsbyoo/p/9028120.html