• spring中使用quartz动态添加定时任务执行sql


    系统用来每天插入视图数据。。。

    一、数据库表设计

    1、接口配置表(t_m_db_interface_config

     

    2、接口日志表(t_m_db_interface_log

     

    3、前端配置页面

    查询页面:

    新增及修改页面:

    第一个sql一般用来删除原有数据,第二个sql一般用来插入新数据,多条sql可以写在一起,代码中做了批处理,用分号隔开(英文的分号)。

    不配置临界时间点时sql示例:delete from table_ where BUSSINESS_DATE>=DATE_FORMAT(NOW(),'%Y-%m-%d');

    配置临界时间点sql示例:delete from table_ where BUSSINESS_DATE>=DATE_FORMAT(?,'%Y-%m-%d');

    时间条件可自己修改,注意的是如果sql中有?号则说明配置了临界时间点,代码中会根据设置的临界时间点来确定是今天还是昨天。

    4、单表类

    上述两张表的字段设计可根据实际需求灵活调整。

    按mvc的开发模式,写出上述两个表对应的对码。也可以Mybatis工具自动分包生成。

    分别位于com.dbs.dmsmdm.(controller/service/mapper/bean).simple路径下。

    xml映射文件位于resources/mybatis+同上路径下。

    这里只贴出bean层代码,Controllor、Service、dao、mapper就不贴出来了。

    前面的@ApiModelProperty注解为自定义的注解,请忽略。。。

      1 package com.dbs.dmsmdm.bean.simple;
      2 
      3 import com.dbs.dms.uibase.bean.BaseBean;
      4 import java.util.Date;
      5 
      6 import org.springframework.format.annotation.DateTimeFormat;
      7 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
      8 import com.fasterxml.jackson.annotation.JsonFormat;
      9 import com.dbs.dms.uibase.annotations.ApiModel;
     10 import com.dbs.dms.uibase.annotations.ApiModelProperty;
     11 import com.dbs.dms.translate.TranslateBean;
     12 import com.dbs.dms.translate.TranslateBeanSerializer;
     13 /**
     14  * 接口配置表
     15  * 实体类对应的数据表为:  t_m_db_interface_config
     16  * @author $Author
     17  * @date Tue Apr 17 11:21:18 GMT+08:00 2018
     18  */
     19 @ApiModel(value ="DbInterfaceConfigBean")
     20 public class DbInterfaceConfigBean extends BaseBean {
     21     public static final String ATTR_INTERFACE_CONFIG_ID = "interfaceConfigId";
     22     public static final String ATTR_INTERFACE_CODE = "interfaceCode";
     23     public static final String ATTR_INTERFACE_NAME = "interfaceName";
     24     public static final String ATTR_FROM_SYSTEM = "fromSystem";
     25     public static final String ATTR_TO_SYSTEM = "toSystem";
     26     public static final String ATTR_FREQENCY = "freqency";
     27     public static final String ATTR_FREQENCY_TYPE = "freqencyType";
     28     public static final String ATTR_BEGIN_RUN_TIME = "beginRunTime";
     29     public static final String ATTR_NEXT_RUN_TIME = "nextRunTime";
     30     public static final String ATTR_TIME_RUN_YESTERDAY = "timeRunYesterday";
     31     public static final String ATTR_BEFORE_SQL = "beforeSql";
     32     public static final String ATTR_RUN_SQL = "runSql";
     33     public static final String ATTR_AFTER_SQL = "afterSql";
     34     
     35     @ApiModelProperty(value = "INTERFACE_CONFIG_ID",label = "接口配置",dataType="varchar(36)",length="36",primary=true,required=true)
     36     private String interfaceConfigId;
     37 
     38     @ApiModelProperty(value = "INTERFACE_CODE",label = "接口编码",dataType="varchar(50)",length="50")
     39     private String interfaceCode;
     40 
     41     @ApiModelProperty(value = "INTERFACE_NAME",label = "接口名称",dataType="varchar(200)",length="200")
     42     private String interfaceName;
     43 
     44     @ApiModelProperty(value = "FROM_SYSTEM",label = "源系统:DB0081",dataType="varchar(20)",length="20")
     45     private String fromSystem;
     46 
     47     @ApiModelProperty(value = "TO_SYSTEM",label = "目标系统:DB0081",dataType="varchar(20)",length="20")
     48     private String toSystem;
     49 
     50     @ApiModelProperty(value = "FREQENCY",label = "接口频率",dataType="integer",length="0")
     51     private Integer freqency;
     52 
     53     @ApiModelProperty(value = "FREQENCY_TYPE",label = "频率类别:DB0082",dataType="varchar(2)",length="2")
     54     private String freqencyType;
     55 
     56     @ApiModelProperty(value = "BEGIN_RUN_TIME",label = "开始运行时间",dataType="datetime",length="0")
     57     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     58     private Date beginRunTime;
     59 
     60     @ApiModelProperty(value = "NEXT_RUN_TIME",label = "下次运行时间",dataType="datetime",length="0")
     61     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     62     private Date nextRunTime;
     63 
     64     @ApiModelProperty(value = "TIME_RUN_YESTERDAY",label = "N点之前执行前一天数据",dataType="integer",length="0")
     65     private Integer timeRunYesterday;
     66 
     67     @ApiModelProperty(value = "CREATOR",label = "创建人",dataType="varchar(50)",length="50",comment="创建人")
     68     private String creator;
     69 
     70     @ApiModelProperty(value = "CREATED_DATE",label = "创建时间",dataType="datetime",length="0",comment="创建时间")
     71     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     72     private Date createdDate;
     73 
     74     @ApiModelProperty(value = "MODIFIER",label = "最后更新人员",dataType="varchar(50)",length="50",comment="最后更新人员")
     75     private String modifier;
     76 
     77     @ApiModelProperty(value = "LAST_UPDATED_DATE",label = "最后更新时间",dataType="timestamp",length="0",comment="最后更新时间")
     78     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     79     private Date lastUpdatedDate;
     80 
     81     @ApiModelProperty(value = "IS_ENABLE",label = "是否可用",dataType="varchar(2)",length="2",comment="是否可用 1启用,0禁用,2删除")
     82     private String isEnable;
     83 
     84     @ApiModelProperty(value = "UPDATE_CONTROL_ID",label = "并发控制字段",dataType="varchar(36)",length="36",comment="并发控制字段")
     85     private String updateControlId;
     86 
     87     public String getInterfaceConfigId() {
     88         return interfaceConfigId;
     89     }
     90 
     91     public void setInterfaceConfigId(String interfaceConfigId) {
     92         this.interfaceConfigId = interfaceConfigId;
     93     }
     94 
     95     public String getInterfaceCode() {
     96         return interfaceCode;
     97     }
     98 
     99     public void setInterfaceCode(String interfaceCode) {
    100         this.interfaceCode = interfaceCode;
    101     }
    102 
    103     public String getInterfaceName() {
    104         return interfaceName;
    105     }
    106 
    107     public void setInterfaceName(String interfaceName) {
    108         this.interfaceName = interfaceName;
    109     }
    110 
    111     public String getFromSystem() {
    112         return fromSystem;
    113     }
    114 
    115     public void setFromSystem(String fromSystem) {
    116         this.fromSystem = fromSystem;
    117     }
    118 
    119     public String getToSystem() {
    120         return toSystem;
    121     }
    122 
    123     public void setToSystem(String toSystem) {
    124         this.toSystem = toSystem;
    125     }
    126 
    127     public Integer getFreqency() {
    128         return freqency;
    129     }
    130 
    131     public void setFreqency(Integer freqency) {
    132         this.freqency = freqency;
    133     }
    134 
    135     public String getFreqencyType() {
    136         return freqencyType;
    137     }
    138 
    139     public void setFreqencyType(String freqencyType) {
    140         this.freqencyType = freqencyType;
    141     }
    142 
    143     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    144     public Date getBeginRunTime() {
    145         return beginRunTime;
    146     }
    147 
    148     public void setBeginRunTime(Date beginRunTime) {
    149         this.beginRunTime = beginRunTime;
    150     }
    151 
    152     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    153     public Date getNextRunTime() {
    154         return nextRunTime;
    155     }
    156 
    157     public void setNextRunTime(Date nextRunTime) {
    158         this.nextRunTime = nextRunTime;
    159     }
    160 
    161     public Integer getTimeRunYesterday() {
    162         return timeRunYesterday;
    163     }
    164 
    165     public void setTimeRunYesterday(Integer timeRunYesterday) {
    166         this.timeRunYesterday = timeRunYesterday;
    167     }
    168 
    169     public String getCreator() {
    170         return creator;
    171     }
    172 
    173     public void setCreator(String creator) {
    174         this.creator = creator;
    175     }
    176 
    177     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    178     public Date getCreatedDate() {
    179         return createdDate;
    180     }
    181 
    182     public void setCreatedDate(Date createdDate) {
    183         this.createdDate = createdDate;
    184     }
    185 
    186     public String getModifier() {
    187         return modifier;
    188     }
    189 
    190     public void setModifier(String modifier) {
    191         this.modifier = modifier;
    192     }
    193 
    194     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    195     public Date getLastUpdatedDate() {
    196         return lastUpdatedDate;
    197     }
    198 
    199     public void setLastUpdatedDate(Date lastUpdatedDate) {
    200         this.lastUpdatedDate = lastUpdatedDate;
    201     }
    202 
    203     public String getIsEnable() {
    204         return isEnable;
    205     }
    206 
    207     public void setIsEnable(String isEnable) {
    208         this.isEnable = isEnable;
    209     }
    210 
    211     public String getUpdateControlId() {
    212         return updateControlId;
    213     }
    214 
    215     public void setUpdateControlId(String updateControlId) {
    216         this.updateControlId = updateControlId;
    217     }
    218 }
    DbInterfaceConfigBean
      1 package com.dbs.dmsmdm.bean.simple;
      2 
      3 import com.dbs.dms.uibase.bean.BaseBean;
      4 import java.util.Date;
      5 
      6 import org.springframework.format.annotation.DateTimeFormat;
      7 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
      8 import com.fasterxml.jackson.annotation.JsonFormat;
      9 import com.dbs.dms.uibase.annotations.ApiModel;
     10 import com.dbs.dms.uibase.annotations.ApiModelProperty;
     11 import com.dbs.dms.translate.TranslateBean;
     12 import com.dbs.dms.translate.TranslateBeanSerializer;
     13 /**
     14  * 接口运行日志
     15  * 实体类对应的数据表为:  t_m_db_interface_log
     16  * @author $Author
     17  * @date Tue Apr 17 11:21:18 GMT+08:00 2018
     18  */
     19 @ApiModel(value ="DbInterfaceLogBean")
     20 public class DbInterfaceLogBean extends BaseBean {
     21     public static final String ATTR_IFTERFACE_LOG_ID = "ifterfaceLogId";
     22     public static final String ATTR_INTERFACE_CODE = "interfaceCode";
     23     public static final String ATTR_INTERFACE_NAME = "interfaceName";
     24     public static final String ATTR_FROM_SYSTEM = "fromSystem";
     25     public static final String ATTR_TO_SYSTEM = "toSystem";
     26     public static final String ATTR_ERROR_TIME = "errorTime";
     27     public static final String ATTR_ERROR_MSG = "errorMsg";
     28     
     29     @ApiModelProperty(value = "IFTERFACE_LOG_ID",label = "IFTERFACE_LOG_ID",dataType="varchar(36)",length="36",primary=true,required=true,comment="ID")
     30     private String ifterfaceLogId;
     31 
     32     @ApiModelProperty(value = "INTERFACE_CODE",label = "接口编码",dataType="varchar(50)",length="50",comment="接口编码")
     33     private String interfaceCode;
     34 
     35     @ApiModelProperty(value = "INTERFACE_NAME",label = "接口名称",dataType="varchar(200)",length="200",comment="接口名称")
     36     private String interfaceName;
     37 
     38     @ApiModelProperty(value = "FROM_SYSTEM",label = "源系统",dataType="varchar(20)",length="20",comment="源系统:DB0081")
     39     private String fromSystem;
     40 
     41     @ApiModelProperty(value = "TO_SYSTEM",label = "目标系统",dataType="varchar(20)",length="20",comment="目标系统:DB0081")
     42     private String toSystem;
     43 
     44     @ApiModelProperty(value = "ERROR_TIME",label = "错误时间",dataType="datetime",length="0",comment="错误时间")
     45     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     46     private Date errorTime;
     47 
     48     @ApiModelProperty(value = "CREATOR",label = "创建人",dataType="varchar(50)",length="50",comment="创建人")
     49     private String creator;
     50 
     51     @ApiModelProperty(value = "CREATED_DATE",label = "创建时间",dataType="datetime",length="0",comment="创建时间")
     52     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     53     private Date createdDate;
     54 
     55     @ApiModelProperty(value = "MODIFIER",label = "最后更新人员",dataType="varchar(50)",length="50",comment="最后更新人员")
     56     private String modifier;
     57 
     58     @ApiModelProperty(value = "LAST_UPDATED_DATE",label = "最后更新时间",dataType="timestamp",length="0",comment="最后更新时间")
     59     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     60     private Date lastUpdatedDate;
     61 
     62     @ApiModelProperty(value = "IS_ENABLE",label = "是否可用",dataType="varchar(2)",length="2",comment="是否可用 1启用,0禁用")
     63     private String isEnable;
     64 
     65     @ApiModelProperty(value = "UPDATE_CONTROL_ID",label = "并发控制字段",dataType="varchar(36)",length="36",comment="并发控制字段")
     66     private String updateControlId;
     67 
     68     @ApiModelProperty(value = "ERROR_MSG",label = "错误信息",dataType="text",length="0",comment="记录数据库报错信息")
     69     private String errorMsg;
     70 
     71     public String getIfterfaceLogId() {
     72         return ifterfaceLogId;
     73     }
     74 
     75     public void setIfterfaceLogId(String ifterfaceLogId) {
     76         this.ifterfaceLogId = ifterfaceLogId;
     77     }
     78 
     79     public String getInterfaceCode() {
     80         return interfaceCode;
     81     }
     82 
     83     public void setInterfaceCode(String interfaceCode) {
     84         this.interfaceCode = interfaceCode;
     85     }
     86 
     87     public String getInterfaceName() {
     88         return interfaceName;
     89     }
     90 
     91     public void setInterfaceName(String interfaceName) {
     92         this.interfaceName = interfaceName;
     93     }
     94 
     95     public String getFromSystem() {
     96         return fromSystem;
     97     }
     98 
     99     public void setFromSystem(String fromSystem) {
    100         this.fromSystem = fromSystem;
    101     }
    102 
    103     public String getToSystem() {
    104         return toSystem;
    105     }
    106 
    107     public void setToSystem(String toSystem) {
    108         this.toSystem = toSystem;
    109     }
    110 
    111     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    112     public Date getErrorTime() {
    113         return errorTime;
    114     }
    115 
    116     public void setErrorTime(Date errorTime) {
    117         this.errorTime = errorTime;
    118     }
    119 
    120     public String getCreator() {
    121         return creator;
    122     }
    123 
    124     public void setCreator(String creator) {
    125         this.creator = creator;
    126     }
    127 
    128     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    129     public Date getCreatedDate() {
    130         return createdDate;
    131     }
    132 
    133     public void setCreatedDate(Date createdDate) {
    134         this.createdDate = createdDate;
    135     }
    136 
    137     public String getModifier() {
    138         return modifier;
    139     }
    140 
    141     public void setModifier(String modifier) {
    142         this.modifier = modifier;
    143     }
    144 
    145     @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    146     public Date getLastUpdatedDate() {
    147         return lastUpdatedDate;
    148     }
    149 
    150     public void setLastUpdatedDate(Date lastUpdatedDate) {
    151         this.lastUpdatedDate = lastUpdatedDate;
    152     }
    153 
    154     public String getIsEnable() {
    155         return isEnable;
    156     }
    157 
    158     public void setIsEnable(String isEnable) {
    159         this.isEnable = isEnable;
    160     }
    161 
    162     public String getUpdateControlId() {
    163         return updateControlId;
    164     }
    165 
    166     public void setUpdateControlId(String updateControlId) {
    167         this.updateControlId = updateControlId;
    168     }
    169 
    170     public String getErrorMsg() {
    171         return errorMsg;
    172     }
    173 
    174     public void setErrorMsg(String errorMsg) {
    175         this.errorMsg = errorMsg;
    176     }
    177 }
    DbInterfaceLogBean

    二、系统定时任务类(InitQuartzJob)

    参考地址:https://blog.csdn.net/u014723529/article/details/51291289

    1、Quartz工具版本说明

    spring3.1以下的版本必须使用quartz1.x系列,3.1以上的版本才支持quartz 2.x,不然会出错。 

    原因:spring对于quartz的支持实现,org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTriggerquartz1.x系列中org.quartz.CronTrigger是个类,而在quartz2.x系列中org.quartz.CronTrigger变成了接口,从而造成无法用spring的方式配置quartz的触发器(trigger

    开发所选版本:spring5.x系列quartz以及quartz-jobs版本2.3.0

    2、开发流程

    ①、类实现ApplicationContextAware接口,重写方法,获取上下文application,写一个init()方法初始化;

    ②、在初始化方法中通过上下文获取调度工厂SchedulerFactoryBean;

    ③、通过调度工厂生产调度Scheduler

    ④、获取数据库资源;

    ⑤、通过单表类的服务层访问接口配置表,得到集合;

    ⑥、遍历接口配置集合,忽略掉null的对象和状态为不可用的对象(1)

    ⑦、根据接口对象的接口编码得到触发器键TriggerKey;

    ⑧、然后用调度构建出触发器CronTrigger,相当于在spring配置文件中定义的bean id=”myTrigger”;

    ⑨、再根据接口类型、接口频率、运行日期、运行时间生成Cron表达式;

    ⑩、当触发器不存在时,将执行任务的类绑定给JobDetail,并将需要传递的参数放入到JobDetailMap中;

    ⑩①、用表达式调度构建器生成新的触发器,将JobDetail和触发器添加到调度中,到此已完成动态调度任务的添加;

    ⑩②、如果触发器已经存在,则只需要用表达式调度构建器生成新的触发器,将新触发器添加到调度中。

    代码如下:

      1 package com.dbs.stat.quartz;
      2 
      3 import java.util.Calendar;
      4 import java.util.HashMap;
      5 import java.util.List;
      6 import java.util.Map;
      7 
      8 import javax.sql.DataSource;
      9 
     10 import org.quartz.CronScheduleBuilder;
     11 import org.quartz.CronTrigger;
     12 import org.quartz.JobBuilder;
     13 import org.quartz.JobDataMap;
     14 import org.quartz.JobDetail;
     15 import org.quartz.Scheduler;
     16 import org.quartz.SchedulerException;
     17 import org.quartz.TriggerBuilder;
     18 import org.quartz.TriggerKey;
     19 import org.slf4j.Logger;
     20 import org.slf4j.LoggerFactory;
     21 import org.springframework.beans.BeansException;
     22 import org.springframework.beans.factory.annotation.Autowired;
     23 import org.springframework.context.ApplicationContext;
     24 import org.springframework.context.ApplicationContextAware;
     25 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
     26 import org.springframework.stereotype.Component;
     27 
     28 import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
     29 import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
     30 import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService;
     31 
     32 /**
     33  * 时间调度类,动态添加定时任务
     34  * 
     35  * @author yeting
     36  *
     37  */
     38 @Component
     39 public class InitQuartzJob implements ApplicationContextAware {
     40     private static final Logger logger = LoggerFactory.getLogger(InitQuartzJob.class);// 日志
     41     private static ApplicationContext applicationContext;// 上下文
     42     public static SchedulerFactoryBean schedulerFactoryBean = null;// 调度工厂
     43 
     44     @Autowired
     45     DbInterfaceConfigBeanService dbInterfaceConfigBeanService;//注入接口配置表的服务层
     46     
     47     @Autowired
     48     DbInterfaceLogBeanService dbInterfaceLogBeanService;//注入接口运行日志表的服务层
     49 
     50     @Override
     51     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
     52         if (null == this.applicationContext) {
     53             this.applicationContext = applicationContext;// 获取上下文
     54         }
     55 
     56     }
     57 
     58     /**
     59      * 初始化方法
     60      */
     61     public void init() {
     62         DataSource dataSource = (DataSource)applicationContext.getBean("dataSource");//连接数据库的资源
     63         schedulerFactoryBean = (SchedulerFactoryBean) applicationContext.getBean(SchedulerFactoryBean.class);// 通过上下文获取调度工厂
     64         Scheduler scheduler = schedulerFactoryBean.getScheduler();// 通过调度工厂获取Scheduler
     65         try {
     66             logger.info(scheduler.getSchedulerName());// 输出日志信息
     67         } catch (SchedulerException e1) {
     68             e1.printStackTrace();
     69         }
     70 
     71         List<DbInterfaceConfigBeanWithBLOBs> interfaceslist = dbInterfaceConfigBeanService.selectAllBean();//查询接口配置表
     72         for (DbInterfaceConfigBeanWithBLOBs interfaceConfigBean : interfaceslist) {//遍历集合
     73             if (null == interfaceConfigBean) {
     74                 continue;//空对象时进入下一轮循环
     75             }
     76             if (!"1".equals(interfaceConfigBean.getIsEnable())){
     77                 continue;//状态为不可用时进入下一轮循环
     78             }
     79             
     80             logger.debug(scheduler + "...........................................add");// 输出日志信息
     81             TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名
     82             CronTrigger trigger=null;
     83             try {
     84                 trigger = (CronTrigger) scheduler.getTrigger(triggerKey);// 获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
     85             } catch (SchedulerException e1) {
     86                 e1.printStackTrace();
     87             }
     88             
     89             Map<String,Object> map=new HashMap<>();//将需要传递给执行任务类的数据放入map中
     90             map.put("interfaceConfigBean", interfaceConfigBean);
     91             map.put("dbInterfaceConfigBeanService", dbInterfaceConfigBeanService);
     92             map.put("dbInterfaceLogBeanService", dbInterfaceLogBeanService);
     93             map.put("dataSource", dataSource);
     94             
     95             //利用工具类根据接口属性得到表达式
     96             String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(), 
     97                                 interfaceConfigBean.getFreqency(),
     98                                 QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime()));
     99             
    100             if (null == trigger) {//如果触发器不存在,就创建一个
    101                 Class clazz =QuartzJobFactory.class;//执行计划任务的类
    102                 
    103                 JobDetail jobDetail = JobBuilder.newJob(clazz)
    104                         .withIdentity(interfaceConfigBean.getInterfaceCode())
    105                         .usingJobData(new JobDataMap(map))
    106                         .build();// 任务执行类,任务名,数据数组
    107                 
    108                 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器
    109                 trigger = TriggerBuilder.newTrigger()//构建新的trigger
    110                         .withIdentity(interfaceConfigBean.getInterfaceConfigId())
    111                         .withSchedule(scheduleBuilder)
    112                         .build();
    113                 try {
    114                     scheduler.scheduleJob(jobDetail, trigger);//设置调度任务
    115                 } catch (SchedulerException e) {
    116                     e.printStackTrace();
    117                 }
    118             } else {//如果触发器已存在,那么更新相应的定时设置;
    119                 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);
    120                 trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
    121                         .usingJobData(new JobDataMap(map))
    122                         .withSchedule(scheduleBuilder).build();//按新的cronExpression表达式重新构建trigger;
    123                 try {
    124                     scheduler.rescheduleJob(triggerKey, trigger);//按新的trigger重新设置job执行
    125                 } catch (SchedulerException e) {
    126                     e.printStackTrace();
    127                 }
    128             }
    129             
    130             interfaceConfigBean.setNextRunTime(QuartzUtil.getBeginRunTime(Calendar.getInstance(),interfaceConfigBean.getFreqencyType(),
    131                     interfaceConfigBean.getFreqency(),QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
    132             if(dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean)==1){//更新可运行接口的下次执行时间
    133                 logger.info("{}接口的下次执行时间为:{}",interfaceConfigBean.getInterfaceCode(), 
    134                         interfaceConfigBean.getNextRunTime());
    135             }
    136         }
    137     }
    138 }
    InitQuartzJob

    三、计划任务执行类(QuartzJobFactory)

    1、开发流程

    ①、类实现Job接口,写一个execute方法,定时任务启动时会执行该方法;

    ②、在方法中接收JobDetail传过来的参数,包括数据库资源、接口配置对象信息等;

    ③、用数据库资源得到数据库连接,用JDBC技术执行sql语句,并将异常信息写入接口日志表;

    ④、更新数据库中对应接口对象的下次执行时间,关闭资源;

    2、执行说明

    ①、可用状态不为‘1’的接口不会执行,且其下次执行时间会为null

    ②、使用trim()方法去掉sql语句前后空格,程序只能识别以‘create’、‘insert’、‘update’、‘delete’开头的sql语句。

    ③、sql识别通不过的接口或报异常的接口的可用状态会被修改为‘0’,下次执行时间会被修改为null

    代码如下:

      1 package com.dbs.stat.quartz;
      2 
      3 import java.sql.Connection;
      4 import java.sql.ResultSet;
      5 import java.sql.SQLException;
      6 import java.sql.Statement;
      7 import java.util.Calendar;
      8 import java.util.Date;
      9 
     10 import javax.sql.DataSource;
     11 
     12 import org.apache.commons.lang3.StringUtils;
     13 import org.quartz.Job;
     14 import org.quartz.JobDataMap;
     15 import org.quartz.JobExecutionContext;
     16 import org.quartz.JobExecutionException;
     17 import org.slf4j.Logger;
     18 import org.slf4j.LoggerFactory;
     19 import org.springframework.stereotype.Component;
     20 
     21 import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
     22 import com.dbs.dmsmdm.bean.simple.DbInterfaceLogBean;
     23 import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
     24 import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService;
     25 
     26 /**
     27  * 计划任务执行类 
     28  * 
     29  * @author yeting
     30  *
     31  */
     32 @Component
     33 public class QuartzJobFactory implements Job{
     34     public static final Logger logger = LoggerFactory.getLogger(QuartzJobFactory.class);
     35 
     36     /**
     37      * 任务执行方法
     38      */
     39     public void execute(JobExecutionContext context) throws JobExecutionException {
     40         Connection conn = null;
     41         Statement st=null;
     42         ResultSet rs=null;
     43         JobDataMap jobDataMap=context.getJobDetail().getJobDataMap();
     44         DataSource dataSource = (DataSource) jobDataMap.get("dataSource");//接收数据库连接资源
     45         DbInterfaceConfigBeanService dbInterfaceConfigBeanService=(DbInterfaceConfigBeanService) jobDataMap.get("dbInterfaceConfigBeanService");
     46         DbInterfaceLogBeanService dbInterfaceLogBeanService=(DbInterfaceLogBeanService) jobDataMap.get("dbInterfaceLogBeanService");
     47         DbInterfaceConfigBeanWithBLOBs interfaceConfigBean = (DbInterfaceConfigBeanWithBLOBs) jobDataMap.get("interfaceConfigBean");
     48         DbInterfaceLogBean interfaceLogBean=(DbInterfaceLogBean) QuartzUtil.getInitializedObject(new DbInterfaceLogBean(), 
     49                 interfaceConfigBean, 1);//初始化日志对象
     50         String beforeSql=interfaceConfigBean.getBeforeSql();
     51         String runSql=interfaceConfigBean.getRunSql();
     52         String afterSql=interfaceConfigBean.getAfterSql();
     53         Calendar calendar=Calendar.getInstance();//任务启动时间日历类
     54         
     55         logger.info("{}任务启动中。。。",interfaceConfigBean.getInterfaceCode());
     56         if(!"1".equals(interfaceConfigBean.getIsEnable())){
     57             return;//状态不可用就结束方法
     58         }
     59         logger.info("{}接口已启动",interfaceConfigBean.getInterfaceCode());
     60         
     61         boolean flag=true;
     62         try {
     63             conn= dataSource.getConnection();
     64             conn.setAutoCommit(false);//打开事务边界,就是取消自动提交,改为手动
     65             st=conn.createStatement();
     66             
     67 /*            st.addBatch("sqls[i]");
     68             st.executeBatch();*/
     69             
     70             if(StringUtils.isNotBlank(beforeSql)){
     71                 beforeSql=beforeSql.trim();
     72                 if(QuartzUtil.getBooleanByCheckSql(beforeSql)){
     73                     String sqls[]=beforeSql.split(";");
     74                     for(int i=0;i<sqls.length;i++){
     75                         sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
     76                         st.addBatch(sqls[i]);
     77                     }
     78                     logger.debug("{}接口 beforeSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);
     79                     st.executeBatch();
     80                 }else{
     81                     flag=false;
     82                     interfaceLogBean.setErrorMsg("beforeSql ERROR");
     83                     dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);
     84                     return;
     85                 }
     86             }
     87             
     88             if(StringUtils.isNotBlank(runSql)){//判断语句是否为空
     89                 runSql=runSql.trim();//去掉前后空格
     90                 if(QuartzUtil.getBooleanByCheckSql(runSql)){//判断语句是否可用
     91                     String sqls[]=runSql.split(";");//将多条语句按 ;切分开
     92                     for(int i=0;i<sqls.length;i++){
     93                         sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
     94                         st.addBatch(sqls[i]);// 将所有的SQL语句添加到Statement中进行批处理
     95                     }
     96                     logger.debug("{}接口 runSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);// 输出日志信息
     97                     st.executeBatch();// 一次执行多条SQL语句
     98                 }else{
     99                     flag=false;
    100                     interfaceLogBean.setErrorMsg("runSql ERROR");
    101                     dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将错误信息插入到日志表
    102                     return;
    103                 }
    104             }
    105             
    106             if(StringUtils.isNotBlank(afterSql)){
    107                 afterSql=afterSql.trim();
    108                 if(QuartzUtil.getBooleanByCheckSql(afterSql)){
    109                     String sqls[]=afterSql.split(";");
    110                     for(int i=0;i<sqls.length;i++){
    111                         sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
    112                         st.addBatch(sqls[i]);
    113                     }
    114                     logger.debug("{}接口 afterSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);
    115                     st.executeBatch();
    116                 }else{
    117                     flag=false;
    118                     interfaceLogBean.setErrorMsg("afterSql ERROR");
    119                     dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);
    120                     return;
    121                 }
    122             }
    123             
    124             if(flag==true){
    125                 interfaceLogBean.setErrorMsg("SUCCESS");
    126                 dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将成功信息插入到日志表
    127             }
    128             
    129             conn.commit();//提交事务,正常结束
    130         } catch (Exception e) {//捕获所有异常
    131             e.printStackTrace();
    132             try {
    133                 conn.rollback();//有异常发生就回滚事务,是为了保证释放锁
    134             } catch (SQLException e1) {
    135                 e1.printStackTrace();
    136             }
    137             
    138             flag=false;
    139             interfaceLogBean.setErrorMsg("ERROR:"+e.getMessage());
    140             dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将错误信息插入到日志表
    141         } finally {
    142             if(flag==true){//利用工具类根据接口属性,设置接口的下次运行时间 
    143                 interfaceConfigBean.setNextRunTime(QuartzUtil.getNextRunTime(calendar,
    144                                             interfaceConfigBean.getFreqencyType(),interfaceConfigBean.getFreqency(),
    145                                             QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
    146             }else{
    147                 interfaceConfigBean.setIsEnable("0");//将接口状态设置为不可用
    148                 interfaceConfigBean.setNextRunTime(null);//接口的下次运行时间为null
    149             }
    150 
    151             if(dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean)==1){//更新接口对象
    152                 logger.debug("{}接口信息已更新,下次执行时间:{}",interfaceConfigBean.getInterfaceCode(), 
    153                         interfaceConfigBean.getNextRunTime());    
    154             }else{
    155                 logger.debug("{}接口信息更新失败",interfaceConfigBean.getInterfaceCode());
    156             }
    157             
    158             QuartzUtil.closeAll(conn, st, rs);//关闭数据库资源
    159             logger.info("{}接口已关闭",interfaceConfigBean.getInterfaceCode());
    160         }
    161     }
    162 }
    QuartzJobFactory

    四、工具类(QuartzUtil)

    本人表示写得很烂,工具类代码里面涉及到业务的代码请忽略。。。

      1 package com.dbs.stat.quartz;
      2 
      3 import java.sql.Connection;
      4 import java.sql.ResultSet;
      5 import java.sql.SQLException;
      6 import java.sql.Statement;
      7 import java.text.SimpleDateFormat;
      8 import java.util.Calendar;
      9 import java.util.Date;
     10 
     11 import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
     12 import com.dbs.dmsmdm.bean.simple.DbInterfaceLogBean;
     13 
     14 /**
     15  * 工具类,优化代码结构
     16  * @author yeting
     17  *
     18  */
     19 public class QuartzUtil {
     20     
     21     /**
     22      * 将日期对象转换为日时分秒数组
     23      * @author yeting
     24      * @param beginRunTime 日期对象
     25      * @return 返回日时分秒数组
     26      */
     27     public static int[] getFormatTime(Date beginRunTime){
     28         int runtime[]=null;
     29         String Hms="";
     30         if(null != beginRunTime){
     31             SimpleDateFormat sdf=new SimpleDateFormat("dd HH:mm:ss");
     32             Hms=sdf.format(beginRunTime);
     33             
     34             runtime=new int[4];
     35             runtime[0]=Integer.valueOf(Hms.substring(0, 2));
     36             runtime[1]=Integer.valueOf(Hms.substring(3, 5));
     37             runtime[2]=Integer.valueOf(Hms.substring(6, 8));
     38             runtime[3]=Integer.valueOf(Hms.substring(9));
     39         }else{
     40             runtime=new int[]{1,0,0,0};//默认值
     41         }
     42         return runtime;
     43     }
     44     
     45     /**
     46      * 根据接口属性生成表达式
     47      * @author yeting
     48      * @param freqencyType 频率类型
     49      * @param freqency 频率值
     50      * @param runTime 日时分秒数组
     51      * @return 返回表达式
     52      */
     53     public static String getCronExpression(String freqencyType,int freqency,int[] runTime){
     54         String CronExpression="";//根据接口的执行频率写表达式
     55         switch(freqencyType){
     56             case "1"://从某分某秒开始,之后每几分钟/次
     57                 CronExpression=runTime[3]+" "+runTime[2]+"/"+(freqency%60!=0?freqency%60:59)+" * * * ?";
     58                 break;
     59             case "2"://从某时某分某秒开始,之后每几小时/次
     60                 CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+"/"+(freqency%24!=0?freqency%24:23)+" * * ?";
     61                 break;
     62             case "3"://某时某分某秒固定执行,每几天/次
     63                 CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+" */"+(freqency%31!=0?freqency%31:31)+" * ?";
     64                 break;
     65             case "4"://某天某时某分某秒固定执行,每几月/次
     66                 CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+" "+runTime[0]+" */"+(freqency%12!=0?freqency%12:12)+" ?";
     67                 break;
     68             default://默认每月1号凌晨00:00:00执行
     69                 CronExpression="0 0 0 1 * ?";
     70                 break;
     71         }
     72         return CronExpression;
     73     }
     74     
     75     /**
     76      * 计算任务的第一次运行时间
     77      * @author yeting
     78      * @param calendar 当前时间日历类
     79      * @param freqencyType 频率类型
     80      * @param freqency 频率
     81      * @param runTime 日时分秒数组
     82      * @return 返回日期对象
     83      */
     84     public static Date getBeginRunTime(Calendar calendar,String freqencyType,int freqency,int[] runTime){
     85         switch (freqencyType) {
     86         case "1"://分钟/次
     87             freqency=(freqency%60!=0?freqency%60:59);
     88             for(int i=0;i<59;i++){
     89                 if(runTime[2]+freqency*i<60){
     90                     if(runTime[2]+freqency*i>=calendar.get(Calendar.MINUTE)){//如果现在分钟小于下次运行分钟,那么取下次运行分钟
     91                         calendar.set(Calendar.MINUTE, runTime[2]+freqency*i);
     92                         break;
     93                     }
     94                     if(runTime[2]+freqency*i==calendar.get(Calendar.MINUTE)){//如果现在分钟等于下次运行分钟
     95                         if(runTime[3]>=calendar.get(Calendar.SECOND)){//如果现在秒钟小于等于开始运行秒钟,那么取开始运行分钟
     96                             calendar.set(Calendar.MINUTE, runTime[2]+freqency*i);
     97                             break;
     98                         }    
     99                     }
    100                 }else{//否则就到下一个小时
    101                     calendar.set(Calendar.MINUTE, runTime[2]);
    102                     calendar.add(Calendar.HOUR_OF_DAY, 1);
    103                     break;
    104                 }
    105             }
    106             calendar.set(Calendar.SECOND, runTime[3]);
    107             break;
    108         case "2"://小时/次
    109             freqency=(freqency%24!=0?freqency%24:23);
    110             for(int i=0;i<24;i++){
    111                 if(runTime[1]+freqency*i<24){
    112                     if(runTime[1]+freqency*i>calendar.get(Calendar.HOUR_OF_DAY)){
    113                         calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
    114                         break;
    115                     }
    116                     if(runTime[1]+freqency*i==calendar.get(Calendar.HOUR_OF_DAY)){
    117                         if(runTime[2]>calendar.get(Calendar.MINUTE)){
    118                             calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
    119                             break;
    120                         }
    121                         if(runTime[2]==calendar.get(Calendar.MINUTE)){
    122                             if(runTime[3]>=calendar.get(Calendar.SECOND)){
    123                                 calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
    124                                 break;
    125                             }
    126                         }    
    127                     }
    128                 }else{
    129                     calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
    130                     calendar.add(Calendar.DAY_OF_MONTH, 1);
    131                     break;
    132                 }
    133             }
    134             calendar.set(Calendar.SECOND, runTime[3]);
    135             calendar.set(Calendar.MINUTE, runTime[2]);
    136             break;
    137         case "3"://天/次
    138             Boolean b=false;
    139             if(runTime[1]>calendar.get(Calendar.HOUR_OF_DAY)){
    140                 b=true;
    141             }
    142             if(runTime[1]==calendar.get(Calendar.HOUR_OF_DAY)){
    143                 if(runTime[2]>calendar.get(Calendar.MINUTE)){
    144                     b=true;
    145                 }
    146                 if(runTime[2]==calendar.get(Calendar.MINUTE)){
    147                     if(runTime[3]>=calendar.get(Calendar.SECOND)){
    148                         b=true;
    149                     }
    150                 }    
    151             }
    152             if(b==false){
    153                 calendar.add(Calendar.DAY_OF_MONTH,1);
    154             }
    155             calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
    156             calendar.set(Calendar.MINUTE, runTime[2]);
    157             calendar.set(Calendar.SECOND, runTime[3]);
    158             break;
    159         case "4"://月/次
    160             Boolean bb=false;
    161             if(runTime[0]>calendar.get(Calendar.DAY_OF_MONTH)){
    162                 bb=true;
    163             }
    164             if(runTime[0]==calendar.get(Calendar.DAY_OF_MONTH)){
    165                 if(runTime[1]>calendar.get(Calendar.HOUR_OF_DAY)){
    166                     bb=true;
    167                 }
    168                 if(runTime[1]==calendar.get(Calendar.HOUR_OF_DAY)){
    169                     if(runTime[2]>calendar.get(Calendar.MINUTE)){
    170                         bb=true;
    171                     }
    172                     if(runTime[2]==calendar.get(Calendar.MINUTE)){
    173                         if(runTime[3]>=calendar.get(Calendar.SECOND)){
    174                             bb=true;
    175                         }
    176                     }    
    177                 }
    178             }
    179             if(bb==false){
    180                 calendar.add(Calendar.MONTH,1);
    181             }
    182             calendar.set(Calendar.DAY_OF_MONTH,runTime[0]);
    183             calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
    184             calendar.set(Calendar.MINUTE, runTime[2]);
    185             calendar.set(Calendar.SECOND, runTime[3]);
    186             break;
    187         default:
    188             calendar.add(Calendar.MONTH,1);
    189             break;
    190         }
    191         
    192         Date date=calendar.getTime(); 
    193         return date;
    194     }
    195     
    196     /**
    197      * 任务启动后计算下次运行时间
    198      * @author yeting
    199      * @param Calendar 任务启动时的时间日历类
    200      * @param freqencyType 频率类型
    201      * @param freqency 频率
    202      * @param runTime 日时分秒数组
    203      * @return 返回日期对象
    204      */
    205     public static Date getNextRunTime(Calendar calendar,String freqencyType,int freqency,int[] runTime){
    206         switch (freqencyType) {
    207         case "1"://分钟/次
    208             freqency=(freqency%60!=0?freqency%60:59);
    209             if(calendar.get(Calendar.MINUTE)+freqency>59){//超过59分钟,就重新从某分开始
    210                 calendar.add(Calendar.HOUR_OF_DAY, 1);
    211                 calendar.set(Calendar.MINUTE, runTime[2]);
    212             }else{//否则分钟加上频率值
    213                 calendar.add(Calendar.MINUTE,freqency);
    214             }
    215             break;
    216         case "2"://小时/次
    217             freqency=(freqency%24!=0?freqency%24:23);
    218             if(calendar.get(Calendar.HOUR_OF_DAY)+freqency>23){//超过23小时,就重新从某小时开始
    219                 calendar.add(Calendar.DAY_OF_MONTH, 1);
    220                 calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
    221             }else{//否则小时加上频率值
    222                 calendar.add(Calendar.HOUR_OF_DAY,freqency);
    223             }
    224             break;
    225         case "3"://天/次
    226             calendar.add(Calendar.DAY_OF_MONTH,(freqency%31!=0?freqency%31:31));
    227             break;
    228         case "4"://月/次
    229             calendar.add(Calendar.MONTH,(freqency%12!=0?freqency%12:12));
    230             break;
    231         default:
    232             calendar.add(Calendar.MONTH,1);
    233             break;
    234         }
    235         
    236         Date date=calendar.getTime(); 
    237         return date;
    238     }
    239     
    240     /**
    241      * 初始化对象
    242      * @param interfaceLogBean 日志对象
    243      * @param interfaceConfigBean 接口对象
    244      * @param type 类型  为1时初始化日志对象
    245      * @return 返回对象
    246      */
    247     public static Object getInitializedObject(DbInterfaceLogBean interfaceLogBean,
    248                                     DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,int type){
    249         Object obj=null;
    250         switch(type){
    251         case 1:
    252             interfaceLogBean.setInterfaceCode(interfaceConfigBean.getInterfaceCode());
    253             interfaceLogBean.setInterfaceName(interfaceConfigBean.getInterfaceName());
    254             interfaceLogBean.setFromSystem(interfaceConfigBean.getFromSystem());
    255             interfaceLogBean.setToSystem(interfaceConfigBean.getToSystem());
    256             interfaceLogBean.setErrorTime(new Date());
    257             interfaceLogBean.setCreatedDate(new Date());
    258             interfaceLogBean.setCreator("System");
    259             interfaceLogBean.setModifier("System");
    260             interfaceLogBean.setLastUpdatedDate(new Date());
    261             interfaceLogBean.setIsEnable("1");
    262             obj=interfaceLogBean;
    263             break;
    264         }
    265         return obj;
    266     }
    267     
    268     /**
    269      * 判断sql语句是否可用
    270      * @param sql 语句
    271      * @return 可用返回true,不可用返回false
    272      */
    273     public static boolean getBooleanByCheckSql(String sql){
    274         boolean flag=false;
    275         if(sql.length()>6){
    276             if("create".equalsIgnoreCase(sql.substring(0, 6))||"insert".equalsIgnoreCase(sql.substring(0, 6))
    277                     ||"update".equalsIgnoreCase(sql.substring(0, 6))||"delete".equalsIgnoreCase(sql.substring(0, 6))){
    278                 flag=true;
    279             }else{
    280                 flag=false;
    281             }
    282         }
    283         return flag;
    284     }
    285     
    286     /**
    287      * 根据临界时间点修改sql语句的时间字段(?)
    288      * @param sql 语句
    289      * @param timeRunYesterday 临界时间点
    290      * @return 返回原sql或替换时间条件后的sql
    291      */
    292     public static String getSqlByTimeRunYesterday(String sql,int timeRunYesterday){
    293         Calendar calendar=Calendar.getInstance();
    294         String newTime="NOW()";
    295         
    296         if(timeRunYesterday>0 && timeRunYesterday<=23){
    297             int nowHour=calendar.get(Calendar.HOUR_OF_DAY);
    298             if(nowHour<timeRunYesterday){
    299                 calendar.add(Calendar.DAY_OF_MONTH, -1);//当前时间小于临界时间点,就执行前一天的数据
    300                 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    301                 newTime="'"+sdf.format(calendar.getTime())+"'";
    302             }
    303         }
    304 
    305         //替换时间条件
    306         if(0<sql.indexOf("?") || 0<sql.indexOf("?")){
    307             sql=sql.replace("?", newTime);
    308             sql=sql.replace("?", newTime);
    309         }
    310         return sql;
    311     }
    312     
    313     /**
    314      * 关闭数据库资源
    315      * @param conn 连接
    316      * @param st 火箭车
    317      * @param rs 结果集
    318      */
    319     public static void closeAll(Connection conn,Statement st,ResultSet rs){
    320         if(rs!=null){
    321             try {
    322                 rs.close();
    323             } catch (SQLException e) {
    324                 e.printStackTrace();
    325             }
    326         }
    327         if(st!=null){
    328             try {
    329                 st.close();
    330             } catch (SQLException e) {
    331                 e.printStackTrace();
    332             }
    333         }
    334         if(conn!=null){
    335             try {
    336                 conn.close();
    337             } catch (SQLException e) {
    338                 e.printStackTrace();
    339             }
    340         }
    341     }
    342 }
    QuartzUtil

    五、配置文件

    applicationContext.xml文件中注册上述(二+三)两个类,如下:

    1 <!-- 初始化Scheduler -->
    2     <bean id="schedulerFactoryBean"
    3     class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
    4     <!-- 初始化job -->
    5     <bean id="initQuartzJob" class="com.dbs.stat.quartz.InitQuartzJob"
    6         init-method="init" lazy-init="false" />
    配置文件

    六、其他说明

    1、页面输入设定的规则说明

    (?代表执行频率)

    ①、?分钟/次:指定每?分钟执行一次。

    详细解释:第一次启动时间为距离当前时间最近的下一分钟整,以后每隔?分钟启动一次;

    ②、?小时/次:指定每?小时执行一次。

    详细解释: 第一次启动时间为距离当前时间最近的下一小时整,以后每隔?小时启动一次;

    ③、?天/次:指定每?天执行一次。

    详细解释: 需要指定某个时间点(时分秒)

    第一次启动时间为距离当前时间最近的下一个时间点,以后每隔?天启动一次;

    ④、?月/次:指定每?月执行一次。

    详细解释: 需要指定某个时间点(天时分秒),目前只能指定1-28号执行,如果指定其他时间则默认为一个月的最后一天执行。

    第一次启动时间为距离当前时间最近的下一个时间点,以后每隔?月启动一次;

    ⑤、?星期/次:暂未指定。

    2、其他说明

    如遇到复杂的定时任务,可在表中加一个Cron_Expression字段,直接写入表达式,在程序中直接获取该字段。

    至此已完成 服务启动添加————————————————————————————————————————————————————

    接下来是实现 手动添加 ————————————————————————————————————————————————————

    七、实现手动添加的代码

    控制层:

      1 package com.dbs.stat.controller.quartzmanager;
      2 
      3 import java.util.Calendar;
      4 import java.util.HashMap;
      5 import java.util.Map;
      6 
      7 import javax.sql.DataSource;
      8 
      9 import org.quartz.CronTrigger;
     10 import org.quartz.Scheduler;
     11 import org.quartz.SchedulerException;
     12 import org.quartz.SchedulerFactory;
     13 import org.quartz.TriggerKey;
     14 import org.quartz.impl.StdSchedulerFactory;
     15 import org.springframework.beans.factory.annotation.Autowired;
     16 import org.springframework.context.ApplicationContext;
     17 import org.springframework.context.support.ClassPathXmlApplicationContext;
     18 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
     19 import org.springframework.stereotype.Controller;
     20 import org.springframework.web.bind.annotation.RequestMapping;
     21 import org.springframework.web.bind.annotation.ResponseBody;
     22 
     23 import com.dbs.dms.config.AppUtil;
     24 import com.dbs.dms.uibase.Result;
     25 import com.dbs.dms.uibase.controller.BaseController;
     26 import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
     27 import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
     28 import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService;
     29 import com.dbs.stat.quartz.QuartzJobFactory;
     30 import com.dbs.stat.quartz.QuartzUtil;
     31 import com.dbs.stat.service.quartzmanager.QuartzManagerService;
     32 
     33 
     34 /**
     35  *  手动管理定时任务
     36  *  
     37  * @author yeting
     38  *
     39  */
     40 @Controller
     41 @RequestMapping("/quartz/Manager")
     42 public class QuartzManagerController extends BaseController{
     43     
     44     @Autowired
     45     AppUtil appUtil;
     46     
     47     @Autowired
     48     DbInterfaceConfigBeanService dbInterfaceConfigBeanService;//注入接口配置表的服务层
     49     
     50     @Autowired
     51     DbInterfaceLogBeanService dbInterfaceLogBeanService;//注入接口运行日志表的服务层
     52     
     53     @Autowired
     54     QuartzManagerService quartzManagerService;//注入管理服务层
     55     
     56     /**
     57      * 修改定时任务
     58      */
     59     @RequestMapping("/change")
     60     @ResponseBody
     61     public Result changeJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean) { 
     62         DataSource dataSource = (DataSource)appUtil.getBean("dataSource");;//获取数据库连接资源
     63         SchedulerFactoryBean schedulerFactoryBean=(SchedulerFactoryBean)appUtil.getBean(SchedulerFactoryBean.class);
     64         Map<String,Object> map=new HashMap<>();//将需要传递给执行任务类的数据放入map中
     65         map.put("interfaceConfigBean", interfaceConfigBean);
     66         map.put("dbInterfaceConfigBeanService", dbInterfaceConfigBeanService);
     67         map.put("dbInterfaceLogBeanService", dbInterfaceLogBeanService);
     68         map.put("dataSource", dataSource);
     69         
     70         Boolean b=false;
     71         CronTrigger trigger=null;
     72         Scheduler scheduler=null;
     73         int effect=0;
     74         try {
     75             scheduler= schedulerFactoryBean.getScheduler();
     76             TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());//id为触发器名
     77             trigger = (CronTrigger) scheduler .getTrigger(triggerKey);  
     78         } catch (SchedulerException e) {
     79             e.printStackTrace();
     80         }
     81         
     82         
     83         switch(interfaceConfigBean.getIsEnable()){
     84         case "0"://启用操作
     85             interfaceConfigBean.setIsEnable("1");//将状态改为启用
     86             interfaceConfigBean.setNextRunTime(QuartzUtil.getBeginRunTime(Calendar.getInstance(),interfaceConfigBean.getFreqencyType(),
     87                     interfaceConfigBean.getFreqency(),QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
     88             map.put("interfaceConfigBean", interfaceConfigBean);//将最新的对象传递过去!!很重要
     89             if (trigger == null) {  
     90                 b=quartzManagerService.addJob(interfaceConfigBean, QuartzJobFactory.class, map,scheduler);//新增 
     91             }else{
     92                 b=quartzManagerService.removeJob(interfaceConfigBean,scheduler);//停用
     93                 b=quartzManagerService.addJob(interfaceConfigBean, QuartzJobFactory.class, map,scheduler);//新增 
     94             }
     95             break; 
     96         case "1"://禁用操作
     97             if (trigger != null) {
     98                 interfaceConfigBean.setIsEnable("0");//将状态改为停用
     99                 interfaceConfigBean.setNextRunTime(null);
    100                 b=quartzManagerService.removeJob(interfaceConfigBean,scheduler);//停用
    101             }
    102             break;
    103         }
    104 
    105         if(b==false){//操作失败
    106             effect=0;
    107         }else{
    108             effect=dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean);//操作成功更新运行接口
    109         }
    110         return buildDbResult(effect, null);
    111     }
    112 }
    QuartzManagerController

    服务层:

      1 package com.dbs.stat.service.quartzmanager;
      2 
      3 import java.util.Map;
      4 
      5 import org.quartz.CronScheduleBuilder;
      6 import org.quartz.CronTrigger;
      7 import org.quartz.JobBuilder;
      8 import org.quartz.JobDataMap;
      9 import org.quartz.JobDetail;
     10 import org.quartz.JobKey;
     11 import org.quartz.Scheduler;
     12 import org.quartz.SchedulerException;
     13 import org.quartz.SchedulerFactory;
     14 import org.quartz.Trigger;
     15 import org.quartz.TriggerBuilder;
     16 import org.quartz.TriggerKey;
     17 import org.quartz.impl.StdSchedulerFactory;
     18 import org.slf4j.Logger;
     19 import org.slf4j.LoggerFactory;
     20 import org.springframework.stereotype.Service;
     21 
     22 import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
     23 import com.dbs.stat.controller.quartzmanager.QuartzManagerController;
     24 import com.dbs.stat.quartz.QuartzJobFactory;
     25 import com.dbs.stat.quartz.QuartzUtil;
     26 
     27 @Service
     28 public class QuartzManagerService {
     29     private static final Logger logger = LoggerFactory.getLogger(QuartzManagerController.class);// 日志
     30 
     31     /**
     32      * 新增一个运行任务
     33      * @param interfaceConfigBean 接口对象
     34      * @param clazz 执行任务的类
     35      * @param map 传递给执行任务对象的数据数组
     36      * @param scheduler 调度对象
     37      * @return 成功返回true,异常返回false
     38      */
     39     public Boolean addJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,Class clazz,Map<String,Object> map,Scheduler scheduler){
     40         Boolean b=true;
     41         try {     
     42             JobDetail jobDetail= JobBuilder.newJob(QuartzJobFactory.class)
     43                     .withIdentity(interfaceConfigBean.getInterfaceCode())
     44                     .setJobData(new JobDataMap(map))
     45                     .build();// 任务执行类,任务名,任务组,数据数组
     46             
     47             String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(), 
     48                                 interfaceConfigBean.getFreqency(),
     49                                 QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime()));
     50             CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器
     51             
     52             TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 触发器
     53             triggerBuilder.withIdentity(interfaceConfigBean.getInterfaceConfigId());// 触发器名
     54             triggerBuilder.startNow();
     55             triggerBuilder.withSchedule(scheduleBuilder);// 触发器时间设定 
     56             
     57             CronTrigger trigger = (CronTrigger) triggerBuilder.build();//创建Trigger对象
     58             scheduler.scheduleJob(jobDetail, trigger);// 调度容器设置JobDetail和Trigger   
     59             if (!scheduler.isShutdown()) { // 启动  
     60                 scheduler.start();  
     61             }
     62             logger.debug("{}...........................运行任务添加成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
     63         } catch (SchedulerException e) {
     64             b=false;
     65             e.printStackTrace();
     66             logger.info("{}...........................运行任务添加失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
     67         }
     68         return b;
     69     }
     70     
     71     /**
     72      * 修改一个运行任务(不可用)
     73      * @param interfaceConfigBean 接口对象
     74      * @param trigger CronTrigger对象
     75      * @param map 数据集合
     76      * @param scheduler 调度对象
     77      * @return 成功返回true,异常返回false
     78      */
     79     public Boolean modifyJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,CronTrigger trigger,Map<String,Object> map,Scheduler scheduler){
     80         Boolean b=true;
     81         try {  
     82             TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名
     83             
     84             String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(), 
     85                     interfaceConfigBean.getFreqency(),
     86                     QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime()));
     87             CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器
     88             
     89             /*trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
     90                     .usingJobData(new JobDataMap(map))
     91                     .withSchedule(scheduleBuilder).build();//按新的cronExpression表达式重新构建trigger;
     92 */            
     93             JobKey jobKey = trigger.getJobKey();
     94             JobDetail detail = scheduler.getJobDetail(jobKey);
     95             detail.getJobDataMap().put("interfaceConfigBean", interfaceConfigBean);//重新给JobDetail中的数据赋值
     96             
     97             scheduler.rescheduleJob(triggerKey, trigger);//修改
     98             logger.debug("{}...........................运行任务修改成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
     99         } catch (SchedulerException e) {
    100             b=false;
    101             e.printStackTrace();
    102             logger.info("{}...........................运行任务修改失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
    103         }
    104         return b;
    105     }
    106     
    107     /**
    108      * 移除一个运行任务
    109      * @param interfaceConfigBean 接口对象
    110      * @param scheduler 调度对象
    111      * @return 成功返回true,异常返回false
    112      */
    113     public Boolean removeJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,Scheduler scheduler){
    114         Boolean b=true;
    115         try {  
    116             TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名
    117             scheduler.pauseTrigger(triggerKey);// 停止触发器  
    118             scheduler.unscheduleJob(triggerKey);// 移除触发器  
    119             scheduler.deleteJob(JobKey.jobKey(interfaceConfigBean.getInterfaceCode()));//删除任务 
    120             logger.debug("{}...........................运行任务移除成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
    121         } catch (SchedulerException e) {
    122             b=false;
    123             e.printStackTrace();
    124             logger.info("{}...........................运行任务移除失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
    125         }
    126         return b;
    127     }
    128     
    129     /**
    130      * @param scheduler 调度对象
    131      * 移除所有任务
    132      */
    133     public  void shutdownJobs(Scheduler scheduler) {  
    134         try {  
    135             if (!scheduler.isShutdown()) {  
    136                 scheduler.shutdown();  
    137             }  
    138         } catch (Exception e) {  
    139             throw new RuntimeException(e);  
    140         }  
    141     } 
    142 }
    QuartzManagerService

    服务层中的修改定时任务不知为啥用不了,所以在控制层中要修改任务时就直接先删除再新增。。。

    有一个BUG当系统中的该条任务未添加但数据库中存的却是已启用时,此时会禁用失败。。。

    以上为本人根据实际项目经验总结并参考其他博主的文章写成,如有错误内容请指正。。。

  • 相关阅读:
    delphi消息发送字符串
    Delphi2007 在Win10 下运行报错 Assertion failure
    python 定时器
    python 直接赋值 深浅拷贝
    python 闭包
    python 对象
    c++ sizeof和strlen
    c++入门笔记(一)
    python实现四种排序逻辑与代码
    webrtc autotest
  • 原文地址:https://www.cnblogs.com/wlxslsb/p/9623817.html
Copyright © 2020-2023  润新知