Quartz动态添加定时任务执行sql(服务启动添加+手动添加)

2023-07-11,,

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

一、数据库表设计

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注解为自定义的注解,请忽略。。。

 package com.dbs.dmsmdm.bean.simple;

 import com.dbs.dms.uibase.bean.BaseBean;
import java.util.Date; import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.dbs.dms.uibase.annotations.ApiModel;
import com.dbs.dms.uibase.annotations.ApiModelProperty;
import com.dbs.dms.translate.TranslateBean;
import com.dbs.dms.translate.TranslateBeanSerializer;
/**
* 接口配置表
* 实体类对应的数据表为: t_m_db_interface_config
* @author $Author
* @date Tue Apr 17 11:21:18 GMT+08:00 2018
*/
@ApiModel(value ="DbInterfaceConfigBean")
public class DbInterfaceConfigBean extends BaseBean {
public static final String ATTR_INTERFACE_CONFIG_ID = "interfaceConfigId";
public static final String ATTR_INTERFACE_CODE = "interfaceCode";
public static final String ATTR_INTERFACE_NAME = "interfaceName";
public static final String ATTR_FROM_SYSTEM = "fromSystem";
public static final String ATTR_TO_SYSTEM = "toSystem";
public static final String ATTR_FREQENCY = "freqency";
public static final String ATTR_FREQENCY_TYPE = "freqencyType";
public static final String ATTR_BEGIN_RUN_TIME = "beginRunTime";
public static final String ATTR_NEXT_RUN_TIME = "nextRunTime";
public static final String ATTR_TIME_RUN_YESTERDAY = "timeRunYesterday";
public static final String ATTR_BEFORE_SQL = "beforeSql";
public static final String ATTR_RUN_SQL = "runSql";
public static final String ATTR_AFTER_SQL = "afterSql"; @ApiModelProperty(value = "INTERFACE_CONFIG_ID",label = "接口配置",dataType="varchar(36)",length="36",primary=true,required=true)
private String interfaceConfigId; @ApiModelProperty(value = "INTERFACE_CODE",label = "接口编码",dataType="varchar(50)",length="50")
private String interfaceCode; @ApiModelProperty(value = "INTERFACE_NAME",label = "接口名称",dataType="varchar(200)",length="200")
private String interfaceName; @ApiModelProperty(value = "FROM_SYSTEM",label = "源系统:DB0081",dataType="varchar(20)",length="20")
private String fromSystem; @ApiModelProperty(value = "TO_SYSTEM",label = "目标系统:DB0081",dataType="varchar(20)",length="20")
private String toSystem; @ApiModelProperty(value = "FREQENCY",label = "接口频率",dataType="integer",length="0")
private Integer freqency; @ApiModelProperty(value = "FREQENCY_TYPE",label = "频率类别:DB0082",dataType="varchar(2)",length="2")
private String freqencyType; @ApiModelProperty(value = "BEGIN_RUN_TIME",label = "开始运行时间",dataType="datetime",length="0")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date beginRunTime; @ApiModelProperty(value = "NEXT_RUN_TIME",label = "下次运行时间",dataType="datetime",length="0")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date nextRunTime; @ApiModelProperty(value = "TIME_RUN_YESTERDAY",label = "N点之前执行前一天数据",dataType="integer",length="0")
private Integer timeRunYesterday; @ApiModelProperty(value = "CREATOR",label = "创建人",dataType="varchar(50)",length="50",comment="创建人")
private String creator; @ApiModelProperty(value = "CREATED_DATE",label = "创建时间",dataType="datetime",length="0",comment="创建时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate; @ApiModelProperty(value = "MODIFIER",label = "最后更新人员",dataType="varchar(50)",length="50",comment="最后更新人员")
private String modifier; @ApiModelProperty(value = "LAST_UPDATED_DATE",label = "最后更新时间",dataType="timestamp",length="0",comment="最后更新时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdatedDate; @ApiModelProperty(value = "IS_ENABLE",label = "是否可用",dataType="varchar(2)",length="2",comment="是否可用 1启用,0禁用,2删除")
private String isEnable; @ApiModelProperty(value = "UPDATE_CONTROL_ID",label = "并发控制字段",dataType="varchar(36)",length="36",comment="并发控制字段")
private String updateControlId; public String getInterfaceConfigId() {
return interfaceConfigId;
} public void setInterfaceConfigId(String interfaceConfigId) {
this.interfaceConfigId = interfaceConfigId;
} public String getInterfaceCode() {
return interfaceCode;
} public void setInterfaceCode(String interfaceCode) {
this.interfaceCode = interfaceCode;
} public String getInterfaceName() {
return interfaceName;
} public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
} public String getFromSystem() {
return fromSystem;
} public void setFromSystem(String fromSystem) {
this.fromSystem = fromSystem;
} public String getToSystem() {
return toSystem;
} public void setToSystem(String toSystem) {
this.toSystem = toSystem;
} public Integer getFreqency() {
return freqency;
} public void setFreqency(Integer freqency) {
this.freqency = freqency;
} public String getFreqencyType() {
return freqencyType;
} public void setFreqencyType(String freqencyType) {
this.freqencyType = freqencyType;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getBeginRunTime() {
return beginRunTime;
} public void setBeginRunTime(Date beginRunTime) {
this.beginRunTime = beginRunTime;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getNextRunTime() {
return nextRunTime;
} public void setNextRunTime(Date nextRunTime) {
this.nextRunTime = nextRunTime;
} public Integer getTimeRunYesterday() {
return timeRunYesterday;
} public void setTimeRunYesterday(Integer timeRunYesterday) {
this.timeRunYesterday = timeRunYesterday;
} public String getCreator() {
return creator;
} public void setCreator(String creator) {
this.creator = creator;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getCreatedDate() {
return createdDate;
} public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
} public String getModifier() {
return modifier;
} public void setModifier(String modifier) {
this.modifier = modifier;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getLastUpdatedDate() {
return lastUpdatedDate;
} public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
} public String getIsEnable() {
return isEnable;
} public void setIsEnable(String isEnable) {
this.isEnable = isEnable;
} public String getUpdateControlId() {
return updateControlId;
} public void setUpdateControlId(String updateControlId) {
this.updateControlId = updateControlId;
}
}

DbInterfaceConfigBean

 package com.dbs.dmsmdm.bean.simple;

 import com.dbs.dms.uibase.bean.BaseBean;
import java.util.Date; import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.dbs.dms.uibase.annotations.ApiModel;
import com.dbs.dms.uibase.annotations.ApiModelProperty;
import com.dbs.dms.translate.TranslateBean;
import com.dbs.dms.translate.TranslateBeanSerializer;
/**
* 接口运行日志
* 实体类对应的数据表为: t_m_db_interface_log
* @author $Author
* @date Tue Apr 17 11:21:18 GMT+08:00 2018
*/
@ApiModel(value ="DbInterfaceLogBean")
public class DbInterfaceLogBean extends BaseBean {
public static final String ATTR_IFTERFACE_LOG_ID = "ifterfaceLogId";
public static final String ATTR_INTERFACE_CODE = "interfaceCode";
public static final String ATTR_INTERFACE_NAME = "interfaceName";
public static final String ATTR_FROM_SYSTEM = "fromSystem";
public static final String ATTR_TO_SYSTEM = "toSystem";
public static final String ATTR_ERROR_TIME = "errorTime";
public static final String ATTR_ERROR_MSG = "errorMsg"; @ApiModelProperty(value = "IFTERFACE_LOG_ID",label = "IFTERFACE_LOG_ID",dataType="varchar(36)",length="36",primary=true,required=true,comment="ID")
private String ifterfaceLogId; @ApiModelProperty(value = "INTERFACE_CODE",label = "接口编码",dataType="varchar(50)",length="50",comment="接口编码")
private String interfaceCode; @ApiModelProperty(value = "INTERFACE_NAME",label = "接口名称",dataType="varchar(200)",length="200",comment="接口名称")
private String interfaceName; @ApiModelProperty(value = "FROM_SYSTEM",label = "源系统",dataType="varchar(20)",length="20",comment="源系统:DB0081")
private String fromSystem; @ApiModelProperty(value = "TO_SYSTEM",label = "目标系统",dataType="varchar(20)",length="20",comment="目标系统:DB0081")
private String toSystem; @ApiModelProperty(value = "ERROR_TIME",label = "错误时间",dataType="datetime",length="0",comment="错误时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date errorTime; @ApiModelProperty(value = "CREATOR",label = "创建人",dataType="varchar(50)",length="50",comment="创建人")
private String creator; @ApiModelProperty(value = "CREATED_DATE",label = "创建时间",dataType="datetime",length="0",comment="创建时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate; @ApiModelProperty(value = "MODIFIER",label = "最后更新人员",dataType="varchar(50)",length="50",comment="最后更新人员")
private String modifier; @ApiModelProperty(value = "LAST_UPDATED_DATE",label = "最后更新时间",dataType="timestamp",length="0",comment="最后更新时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdatedDate; @ApiModelProperty(value = "IS_ENABLE",label = "是否可用",dataType="varchar(2)",length="2",comment="是否可用 1启用,0禁用")
private String isEnable; @ApiModelProperty(value = "UPDATE_CONTROL_ID",label = "并发控制字段",dataType="varchar(36)",length="36",comment="并发控制字段")
private String updateControlId; @ApiModelProperty(value = "ERROR_MSG",label = "错误信息",dataType="text",length="0",comment="记录数据库报错信息")
private String errorMsg; public String getIfterfaceLogId() {
return ifterfaceLogId;
} public void setIfterfaceLogId(String ifterfaceLogId) {
this.ifterfaceLogId = ifterfaceLogId;
} public String getInterfaceCode() {
return interfaceCode;
} public void setInterfaceCode(String interfaceCode) {
this.interfaceCode = interfaceCode;
} public String getInterfaceName() {
return interfaceName;
} public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
} public String getFromSystem() {
return fromSystem;
} public void setFromSystem(String fromSystem) {
this.fromSystem = fromSystem;
} public String getToSystem() {
return toSystem;
} public void setToSystem(String toSystem) {
this.toSystem = toSystem;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getErrorTime() {
return errorTime;
} public void setErrorTime(Date errorTime) {
this.errorTime = errorTime;
} public String getCreator() {
return creator;
} public void setCreator(String creator) {
this.creator = creator;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getCreatedDate() {
return createdDate;
} public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
} public String getModifier() {
return modifier;
} public void setModifier(String modifier) {
this.modifier = modifier;
} @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getLastUpdatedDate() {
return lastUpdatedDate;
} public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
} public String getIsEnable() {
return isEnable;
} public void setIsEnable(String isEnable) {
this.isEnable = isEnable;
} public String getUpdateControlId() {
return updateControlId;
} public void setUpdateControlId(String updateControlId) {
this.updateControlId = updateControlId;
} public String getErrorMsg() {
return errorMsg;
} public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}

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.CronTrigger。在quartz1.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,并将需要传递的参数放入到JobDetail的Map中;

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

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

代码如下:

 package com.dbs.stat.quartz;

 import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.sql.DataSource; import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component; import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService; /**
* 时间调度类,动态添加定时任务
*
* @author yeting
*
*/
@Component
public class InitQuartzJob implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(InitQuartzJob.class);// 日志
private static ApplicationContext applicationContext;// 上下文
public static SchedulerFactoryBean schedulerFactoryBean = null;// 调度工厂 @Autowired
DbInterfaceConfigBeanService dbInterfaceConfigBeanService;//注入接口配置表的服务层 @Autowired
DbInterfaceLogBeanService dbInterfaceLogBeanService;//注入接口运行日志表的服务层 @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (null == this.applicationContext) {
this.applicationContext = applicationContext;// 获取上下文
} } /**
* 初始化方法
*/
public void init() {
DataSource dataSource = (DataSource)applicationContext.getBean("dataSource");//连接数据库的资源
schedulerFactoryBean = (SchedulerFactoryBean) applicationContext.getBean(SchedulerFactoryBean.class);// 通过上下文获取调度工厂
Scheduler scheduler = schedulerFactoryBean.getScheduler();// 通过调度工厂获取Scheduler
try {
logger.info(scheduler.getSchedulerName());// 输出日志信息
} catch (SchedulerException e1) {
e1.printStackTrace();
} List<DbInterfaceConfigBeanWithBLOBs> interfaceslist = dbInterfaceConfigBeanService.selectAllBean();//查询接口配置表
for (DbInterfaceConfigBeanWithBLOBs interfaceConfigBean : interfaceslist) {//遍历集合
if (null == interfaceConfigBean) {
continue;//空对象时进入下一轮循环
}
if (!"1".equals(interfaceConfigBean.getIsEnable())){
continue;//状态为不可用时进入下一轮循环
} logger.debug(scheduler + "...........................................add");// 输出日志信息
TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名
CronTrigger trigger=null;
try {
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);// 获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
} catch (SchedulerException e1) {
e1.printStackTrace();
} Map<String,Object> map=new HashMap<>();//将需要传递给执行任务类的数据放入map中
map.put("interfaceConfigBean", interfaceConfigBean);
map.put("dbInterfaceConfigBeanService", dbInterfaceConfigBeanService);
map.put("dbInterfaceLogBeanService", dbInterfaceLogBeanService);
map.put("dataSource", dataSource); //利用工具类根据接口属性得到表达式
String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(),
interfaceConfigBean.getFreqency(),
QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())); if (null == trigger) {//如果触发器不存在,就创建一个
Class clazz =QuartzJobFactory.class;//执行计划任务的类 JobDetail jobDetail = JobBuilder.newJob(clazz)
.withIdentity(interfaceConfigBean.getInterfaceCode())
.usingJobData(new JobDataMap(map))
.build();// 任务执行类,任务名,数据数组 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器
trigger = TriggerBuilder.newTrigger()//构建新的trigger
.withIdentity(interfaceConfigBean.getInterfaceConfigId())
.withSchedule(scheduleBuilder)
.build();
try {
scheduler.scheduleJob(jobDetail, trigger);//设置调度任务
} catch (SchedulerException e) {
e.printStackTrace();
}
} else {//如果触发器已存在,那么更新相应的定时设置;
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.usingJobData(new JobDataMap(map))
.withSchedule(scheduleBuilder).build();//按新的cronExpression表达式重新构建trigger;
try {
scheduler.rescheduleJob(triggerKey, trigger);//按新的trigger重新设置job执行
} catch (SchedulerException e) {
e.printStackTrace();
}
} interfaceConfigBean.setNextRunTime(QuartzUtil.getBeginRunTime(Calendar.getInstance(),interfaceConfigBean.getFreqencyType(),
interfaceConfigBean.getFreqency(),QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
if(dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean)==1){//更新可运行接口的下次执行时间
logger.info("{}接口的下次执行时间为:{}",interfaceConfigBean.getInterfaceCode(),
interfaceConfigBean.getNextRunTime());
}
}
}
}

InitQuartzJob

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

1、开发流程

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

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

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

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

2、执行说明

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

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

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

代码如下:

 package com.dbs.stat.quartz;

 import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.Date; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
import com.dbs.dmsmdm.bean.simple.DbInterfaceLogBean;
import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService; /**
* 计划任务执行类
*
* @author yeting
*
*/
@Component
public class QuartzJobFactory implements Job{
public static final Logger logger = LoggerFactory.getLogger(QuartzJobFactory.class); /**
* 任务执行方法
*/
public void execute(JobExecutionContext context) throws JobExecutionException {
Connection conn = null;
Statement st=null;
ResultSet rs=null;
JobDataMap jobDataMap=context.getJobDetail().getJobDataMap();
DataSource dataSource = (DataSource) jobDataMap.get("dataSource");//接收数据库连接资源
DbInterfaceConfigBeanService dbInterfaceConfigBeanService=(DbInterfaceConfigBeanService) jobDataMap.get("dbInterfaceConfigBeanService");
DbInterfaceLogBeanService dbInterfaceLogBeanService=(DbInterfaceLogBeanService) jobDataMap.get("dbInterfaceLogBeanService");
DbInterfaceConfigBeanWithBLOBs interfaceConfigBean = (DbInterfaceConfigBeanWithBLOBs) jobDataMap.get("interfaceConfigBean");
DbInterfaceLogBean interfaceLogBean=(DbInterfaceLogBean) QuartzUtil.getInitializedObject(new DbInterfaceLogBean(),
interfaceConfigBean, 1);//初始化日志对象
String beforeSql=interfaceConfigBean.getBeforeSql();
String runSql=interfaceConfigBean.getRunSql();
String afterSql=interfaceConfigBean.getAfterSql();
Calendar calendar=Calendar.getInstance();//任务启动时间日历类 logger.info("{}任务启动中。。。",interfaceConfigBean.getInterfaceCode());
if(!"1".equals(interfaceConfigBean.getIsEnable())){
return;//状态不可用就结束方法
}
logger.info("{}接口已启动",interfaceConfigBean.getInterfaceCode()); boolean flag=true;
try {
conn= dataSource.getConnection();
conn.setAutoCommit(false);//打开事务边界,就是取消自动提交,改为手动
st=conn.createStatement(); /* st.addBatch("sqls[i]");
st.executeBatch();*/ if(StringUtils.isNotBlank(beforeSql)){
beforeSql=beforeSql.trim();
if(QuartzUtil.getBooleanByCheckSql(beforeSql)){
String sqls[]=beforeSql.split(";");
for(int i=0;i<sqls.length;i++){
sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
st.addBatch(sqls[i]);
}
logger.debug("{}接口 beforeSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);
st.executeBatch();
}else{
flag=false;
interfaceLogBean.setErrorMsg("beforeSql ERROR");
dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);
return;
}
} if(StringUtils.isNotBlank(runSql)){//判断语句是否为空
runSql=runSql.trim();//去掉前后空格
if(QuartzUtil.getBooleanByCheckSql(runSql)){//判断语句是否可用
String sqls[]=runSql.split(";");//将多条语句按 ;切分开
for(int i=0;i<sqls.length;i++){
sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
st.addBatch(sqls[i]);// 将所有的SQL语句添加到Statement中进行批处理
}
logger.debug("{}接口 runSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);// 输出日志信息
st.executeBatch();// 一次执行多条SQL语句
}else{
flag=false;
interfaceLogBean.setErrorMsg("runSql ERROR");
dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将错误信息插入到日志表
return;
}
} if(StringUtils.isNotBlank(afterSql)){
afterSql=afterSql.trim();
if(QuartzUtil.getBooleanByCheckSql(afterSql)){
String sqls[]=afterSql.split(";");
for(int i=0;i<sqls.length;i++){
sqls[i]=QuartzUtil.getSqlByTimeRunYesterday(sqls[i],interfaceConfigBean.getTimeRunYesterday());
st.addBatch(sqls[i]);
}
logger.debug("{}接口 afterSql执行中,共{}条",interfaceConfigBean.getInterfaceCode(),sqls.length);
st.executeBatch();
}else{
flag=false;
interfaceLogBean.setErrorMsg("afterSql ERROR");
dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);
return;
}
} if(flag==true){
interfaceLogBean.setErrorMsg("SUCCESS");
dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将成功信息插入到日志表
} conn.commit();//提交事务,正常结束
} catch (Exception e) {//捕获所有异常
e.printStackTrace();
try {
conn.rollback();//有异常发生就回滚事务,是为了保证释放锁
} catch (SQLException e1) {
e1.printStackTrace();
} flag=false;
interfaceLogBean.setErrorMsg("ERROR:"+e.getMessage());
dbInterfaceLogBeanService.insertSystemLog(interfaceLogBean);//将错误信息插入到日志表
} finally {
if(flag==true){//利用工具类根据接口属性,设置接口的下次运行时间
interfaceConfigBean.setNextRunTime(QuartzUtil.getNextRunTime(calendar,
interfaceConfigBean.getFreqencyType(),interfaceConfigBean.getFreqency(),
QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
}else{
interfaceConfigBean.setIsEnable("0");//将接口状态设置为不可用
interfaceConfigBean.setNextRunTime(null);//接口的下次运行时间为null
} if(dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean)==1){//更新接口对象
logger.debug("{}接口信息已更新,下次执行时间:{}",interfaceConfigBean.getInterfaceCode(),
interfaceConfigBean.getNextRunTime());
}else{
logger.debug("{}接口信息更新失败",interfaceConfigBean.getInterfaceCode());
} QuartzUtil.closeAll(conn, st, rs);//关闭数据库资源
logger.info("{}接口已关闭",interfaceConfigBean.getInterfaceCode());
}
}
}

QuartzJobFactory

四、工具类(QuartzUtil)

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

 package com.dbs.stat.quartz;

 import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
import com.dbs.dmsmdm.bean.simple.DbInterfaceLogBean; /**
* 工具类,优化代码结构
* @author yeting
*
*/
public class QuartzUtil { /**
* 将日期对象转换为日时分秒数组
* @author yeting
* @param beginRunTime 日期对象
* @return 返回日时分秒数组
*/
public static int[] getFormatTime(Date beginRunTime){
int runtime[]=null;
String Hms="";
if(null != beginRunTime){
SimpleDateFormat sdf=new SimpleDateFormat("dd HH:mm:ss");
Hms=sdf.format(beginRunTime); runtime=new int[4];
runtime[0]=Integer.valueOf(Hms.substring(0, 2));
runtime[1]=Integer.valueOf(Hms.substring(3, 5));
runtime[2]=Integer.valueOf(Hms.substring(6, 8));
runtime[3]=Integer.valueOf(Hms.substring(9));
}else{
runtime=new int[]{1,0,0,0};//默认值
}
return runtime;
} /**
* 根据接口属性生成表达式
* @author yeting
* @param freqencyType 频率类型
* @param freqency 频率值
* @param runTime 日时分秒数组
* @return 返回表达式
*/
public static String getCronExpression(String freqencyType,int freqency,int[] runTime){
String CronExpression="";//根据接口的执行频率写表达式
switch(freqencyType){
case "1"://从某分某秒开始,之后每几分钟/次
CronExpression=runTime[3]+" "+runTime[2]+"/"+(freqency%60!=0?freqency%60:59)+" * * * ?";
break;
case "2"://从某时某分某秒开始,之后每几小时/次
CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+"/"+(freqency%24!=0?freqency%24:23)+" * * ?";
break;
case "3"://某时某分某秒固定执行,每几天/次
CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+" */"+(freqency%31!=0?freqency%31:31)+" * ?";
break;
case "4"://某天某时某分某秒固定执行,每几月/次
CronExpression=runTime[3]+" "+runTime[2]+" "+runTime[1]+" "+runTime[0]+" */"+(freqency%12!=0?freqency%12:12)+" ?";
break;
default://默认每月1号凌晨00:00:00执行
CronExpression="0 0 0 1 * ?";
break;
}
return CronExpression;
} /**
* 计算任务的第一次运行时间
* @author yeting
* @param calendar 当前时间日历类
* @param freqencyType 频率类型
* @param freqency 频率
* @param runTime 日时分秒数组
* @return 返回日期对象
*/
public static Date getBeginRunTime(Calendar calendar,String freqencyType,int freqency,int[] runTime){
switch (freqencyType) {
case "1"://分钟/次
freqency=(freqency%60!=0?freqency%60:59);
for(int i=0;i<59;i++){
if(runTime[2]+freqency*i<60){
if(runTime[2]+freqency*i>=calendar.get(Calendar.MINUTE)){//如果现在分钟小于下次运行分钟,那么取下次运行分钟
calendar.set(Calendar.MINUTE, runTime[2]+freqency*i);
break;
}
if(runTime[2]+freqency*i==calendar.get(Calendar.MINUTE)){//如果现在分钟等于下次运行分钟
if(runTime[3]>=calendar.get(Calendar.SECOND)){//如果现在秒钟小于等于开始运行秒钟,那么取开始运行分钟
calendar.set(Calendar.MINUTE, runTime[2]+freqency*i);
break;
}
}
}else{//否则就到下一个小时
calendar.set(Calendar.MINUTE, runTime[2]);
calendar.add(Calendar.HOUR_OF_DAY, 1);
break;
}
}
calendar.set(Calendar.SECOND, runTime[3]);
break;
case "2"://小时/次
freqency=(freqency%24!=0?freqency%24:23);
for(int i=0;i<24;i++){
if(runTime[1]+freqency*i<24){
if(runTime[1]+freqency*i>calendar.get(Calendar.HOUR_OF_DAY)){
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
break;
}
if(runTime[1]+freqency*i==calendar.get(Calendar.HOUR_OF_DAY)){
if(runTime[2]>calendar.get(Calendar.MINUTE)){
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
break;
}
if(runTime[2]==calendar.get(Calendar.MINUTE)){
if(runTime[3]>=calendar.get(Calendar.SECOND)){
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]+freqency*i);
break;
}
}
}
}else{
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
calendar.add(Calendar.DAY_OF_MONTH, 1);
break;
}
}
calendar.set(Calendar.SECOND, runTime[3]);
calendar.set(Calendar.MINUTE, runTime[2]);
break;
case "3"://天/次
Boolean b=false;
if(runTime[1]>calendar.get(Calendar.HOUR_OF_DAY)){
b=true;
}
if(runTime[1]==calendar.get(Calendar.HOUR_OF_DAY)){
if(runTime[2]>calendar.get(Calendar.MINUTE)){
b=true;
}
if(runTime[2]==calendar.get(Calendar.MINUTE)){
if(runTime[3]>=calendar.get(Calendar.SECOND)){
b=true;
}
}
}
if(b==false){
calendar.add(Calendar.DAY_OF_MONTH,1);
}
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
calendar.set(Calendar.MINUTE, runTime[2]);
calendar.set(Calendar.SECOND, runTime[3]);
break;
case "4"://月/次
Boolean bb=false;
if(runTime[0]>calendar.get(Calendar.DAY_OF_MONTH)){
bb=true;
}
if(runTime[0]==calendar.get(Calendar.DAY_OF_MONTH)){
if(runTime[1]>calendar.get(Calendar.HOUR_OF_DAY)){
bb=true;
}
if(runTime[1]==calendar.get(Calendar.HOUR_OF_DAY)){
if(runTime[2]>calendar.get(Calendar.MINUTE)){
bb=true;
}
if(runTime[2]==calendar.get(Calendar.MINUTE)){
if(runTime[3]>=calendar.get(Calendar.SECOND)){
bb=true;
}
}
}
}
if(bb==false){
calendar.add(Calendar.MONTH,1);
}
calendar.set(Calendar.DAY_OF_MONTH,runTime[0]);
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
calendar.set(Calendar.MINUTE, runTime[2]);
calendar.set(Calendar.SECOND, runTime[3]);
break;
default:
calendar.add(Calendar.MONTH,1);
break;
} Date date=calendar.getTime();
return date;
} /**
* 任务启动后计算下次运行时间
* @author yeting
* @param Calendar 任务启动时的时间日历类
* @param freqencyType 频率类型
* @param freqency 频率
* @param runTime 日时分秒数组
* @return 返回日期对象
*/
public static Date getNextRunTime(Calendar calendar,String freqencyType,int freqency,int[] runTime){
switch (freqencyType) {
case "1"://分钟/次
freqency=(freqency%60!=0?freqency%60:59);
if(calendar.get(Calendar.MINUTE)+freqency>59){//超过59分钟,就重新从某分开始
calendar.add(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.MINUTE, runTime[2]);
}else{//否则分钟加上频率值
calendar.add(Calendar.MINUTE,freqency);
}
break;
case "2"://小时/次
freqency=(freqency%24!=0?freqency%24:23);
if(calendar.get(Calendar.HOUR_OF_DAY)+freqency>23){//超过23小时,就重新从某小时开始
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, runTime[1]);
}else{//否则小时加上频率值
calendar.add(Calendar.HOUR_OF_DAY,freqency);
}
break;
case "3"://天/次
calendar.add(Calendar.DAY_OF_MONTH,(freqency%31!=0?freqency%31:31));
break;
case "4"://月/次
calendar.add(Calendar.MONTH,(freqency%12!=0?freqency%12:12));
break;
default:
calendar.add(Calendar.MONTH,1);
break;
} Date date=calendar.getTime();
return date;
} /**
* 初始化对象
* @param interfaceLogBean 日志对象
* @param interfaceConfigBean 接口对象
* @param type 类型 为1时初始化日志对象
* @return 返回对象
*/
public static Object getInitializedObject(DbInterfaceLogBean interfaceLogBean,
DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,int type){
Object obj=null;
switch(type){
case 1:
interfaceLogBean.setInterfaceCode(interfaceConfigBean.getInterfaceCode());
interfaceLogBean.setInterfaceName(interfaceConfigBean.getInterfaceName());
interfaceLogBean.setFromSystem(interfaceConfigBean.getFromSystem());
interfaceLogBean.setToSystem(interfaceConfigBean.getToSystem());
interfaceLogBean.setErrorTime(new Date());
interfaceLogBean.setCreatedDate(new Date());
interfaceLogBean.setCreator("System");
interfaceLogBean.setModifier("System");
interfaceLogBean.setLastUpdatedDate(new Date());
interfaceLogBean.setIsEnable("1");
obj=interfaceLogBean;
break;
}
return obj;
} /**
* 判断sql语句是否可用
* @param sql 语句
* @return 可用返回true,不可用返回false
*/
public static boolean getBooleanByCheckSql(String sql){
boolean flag=false;
if(sql.length()>6){
if("create".equalsIgnoreCase(sql.substring(0, 6))||"insert".equalsIgnoreCase(sql.substring(0, 6))
||"update".equalsIgnoreCase(sql.substring(0, 6))||"delete".equalsIgnoreCase(sql.substring(0, 6))){
flag=true;
}else{
flag=false;
}
}
return flag;
} /**
* 根据临界时间点修改sql语句的时间字段(?)
* @param sql 语句
* @param timeRunYesterday 临界时间点
* @return 返回原sql或替换时间条件后的sql
*/
public static String getSqlByTimeRunYesterday(String sql,int timeRunYesterday){
Calendar calendar=Calendar.getInstance();
String newTime="NOW()"; if(timeRunYesterday>0 && timeRunYesterday<=23){
int nowHour=calendar.get(Calendar.HOUR_OF_DAY);
if(nowHour<timeRunYesterday){
calendar.add(Calendar.DAY_OF_MONTH, -1);//当前时间小于临界时间点,就执行前一天的数据
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
newTime="'"+sdf.format(calendar.getTime())+"'";
}
} //替换时间条件
if(0<sql.indexOf("?") || 0<sql.indexOf("?")){
sql=sql.replace("?", newTime);
sql=sql.replace("?", newTime);
}
return sql;
} /**
* 关闭数据库资源
* @param conn 连接
* @param st 火箭车
* @param rs 结果集
*/
public static void closeAll(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

QuartzUtil

五、配置文件

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

 <!-- 初始化Scheduler -->
<bean id="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<!-- 初始化job -->
<bean id="initQuartzJob" class="com.dbs.stat.quartz.InitQuartzJob"
init-method="init" lazy-init="false" />

配置文件

六、其他说明

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

(?代表执行频率)

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

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

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

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

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

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

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

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

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

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

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

2、其他说明

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

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

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

七、实现手动添加的代码

控制层:

 package com.dbs.stat.controller.quartzmanager;

 import java.util.Calendar;
import java.util.HashMap;
import java.util.Map; import javax.sql.DataSource; import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.dbs.dms.config.AppUtil;
import com.dbs.dms.uibase.Result;
import com.dbs.dms.uibase.controller.BaseController;
import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
import com.dbs.dmsmdm.service.simple.DbInterfaceConfigBeanService;
import com.dbs.dmsmdm.service.simple.DbInterfaceLogBeanService;
import com.dbs.stat.quartz.QuartzJobFactory;
import com.dbs.stat.quartz.QuartzUtil;
import com.dbs.stat.service.quartzmanager.QuartzManagerService; /**
* 手动管理定时任务
*
* @author yeting
*
*/
@Controller
@RequestMapping("/quartz/Manager")
public class QuartzManagerController extends BaseController{ @Autowired
AppUtil appUtil; @Autowired
DbInterfaceConfigBeanService dbInterfaceConfigBeanService;//注入接口配置表的服务层 @Autowired
DbInterfaceLogBeanService dbInterfaceLogBeanService;//注入接口运行日志表的服务层 @Autowired
QuartzManagerService quartzManagerService;//注入管理服务层 /**
* 修改定时任务
*/
@RequestMapping("/change")
@ResponseBody
public Result changeJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean) {
DataSource dataSource = (DataSource)appUtil.getBean("dataSource");;//获取数据库连接资源
SchedulerFactoryBean schedulerFactoryBean=(SchedulerFactoryBean)appUtil.getBean(SchedulerFactoryBean.class);
Map<String,Object> map=new HashMap<>();//将需要传递给执行任务类的数据放入map中
map.put("interfaceConfigBean", interfaceConfigBean);
map.put("dbInterfaceConfigBeanService", dbInterfaceConfigBeanService);
map.put("dbInterfaceLogBeanService", dbInterfaceLogBeanService);
map.put("dataSource", dataSource); Boolean b=false;
CronTrigger trigger=null;
Scheduler scheduler=null;
int effect=0;
try {
scheduler= schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());//id为触发器名
trigger = (CronTrigger) scheduler .getTrigger(triggerKey);
} catch (SchedulerException e) {
e.printStackTrace();
} switch(interfaceConfigBean.getIsEnable()){
case "0"://启用操作
interfaceConfigBean.setIsEnable("1");//将状态改为启用
interfaceConfigBean.setNextRunTime(QuartzUtil.getBeginRunTime(Calendar.getInstance(),interfaceConfigBean.getFreqencyType(),
interfaceConfigBean.getFreqency(),QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime())));
map.put("interfaceConfigBean", interfaceConfigBean);//将最新的对象传递过去!!很重要
if (trigger == null) {
b=quartzManagerService.addJob(interfaceConfigBean, QuartzJobFactory.class, map,scheduler);//新增
}else{
b=quartzManagerService.removeJob(interfaceConfigBean,scheduler);//停用
b=quartzManagerService.addJob(interfaceConfigBean, QuartzJobFactory.class, map,scheduler);//新增
}
break;
case "1"://禁用操作
if (trigger != null) {
interfaceConfigBean.setIsEnable("0");//将状态改为停用
interfaceConfigBean.setNextRunTime(null);
b=quartzManagerService.removeJob(interfaceConfigBean,scheduler);//停用
}
break;
} if(b==false){//操作失败
effect=0;
}else{
effect=dbInterfaceConfigBeanService.updateOneBean(interfaceConfigBean);//操作成功更新运行接口
}
return buildDbResult(effect, null);
}
}

QuartzManagerController

服务层:

 package com.dbs.stat.service.quartzmanager;

 import java.util.Map;

 import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import com.dbs.dmsmdm.bean.simple.DbInterfaceConfigBeanWithBLOBs;
import com.dbs.stat.controller.quartzmanager.QuartzManagerController;
import com.dbs.stat.quartz.QuartzJobFactory;
import com.dbs.stat.quartz.QuartzUtil; @Service
public class QuartzManagerService {
private static final Logger logger = LoggerFactory.getLogger(QuartzManagerController.class);// 日志 /**
* 新增一个运行任务
* @param interfaceConfigBean 接口对象
* @param clazz 执行任务的类
* @param map 传递给执行任务对象的数据数组
* @param scheduler 调度对象
* @return 成功返回true,异常返回false
*/
public Boolean addJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,Class clazz,Map<String,Object> map,Scheduler scheduler){
Boolean b=true;
try {
JobDetail jobDetail= JobBuilder.newJob(QuartzJobFactory.class)
.withIdentity(interfaceConfigBean.getInterfaceCode())
.setJobData(new JobDataMap(map))
.build();// 任务执行类,任务名,任务组,数据数组 String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(),
interfaceConfigBean.getFreqency(),
QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime()));
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 触发器
triggerBuilder.withIdentity(interfaceConfigBean.getInterfaceConfigId());// 触发器名
triggerBuilder.startNow();
triggerBuilder.withSchedule(scheduleBuilder);// 触发器时间设定 CronTrigger trigger = (CronTrigger) triggerBuilder.build();//创建Trigger对象
scheduler.scheduleJob(jobDetail, trigger);// 调度容器设置JobDetail和Trigger
if (!scheduler.isShutdown()) { // 启动
scheduler.start();
}
logger.debug("{}...........................运行任务添加成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
} catch (SchedulerException e) {
b=false;
e.printStackTrace();
logger.info("{}...........................运行任务添加失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
}
return b;
} /**
* 修改一个运行任务(不可用)
* @param interfaceConfigBean 接口对象
* @param trigger CronTrigger对象
* @param map 数据集合
* @param scheduler 调度对象
* @return 成功返回true,异常返回false
*/
public Boolean modifyJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,CronTrigger trigger,Map<String,Object> map,Scheduler scheduler){
Boolean b=true;
try {
TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名 String CronExpression=QuartzUtil.getCronExpression(interfaceConfigBean.getFreqencyType(),
interfaceConfigBean.getFreqency(),
QuartzUtil.getFormatTime(interfaceConfigBean.getBeginRunTime()));
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(CronExpression);//表达式调度构建器 /*trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.usingJobData(new JobDataMap(map))
.withSchedule(scheduleBuilder).build();//按新的cronExpression表达式重新构建trigger;
*/
JobKey jobKey = trigger.getJobKey();
JobDetail detail = scheduler.getJobDetail(jobKey);
detail.getJobDataMap().put("interfaceConfigBean", interfaceConfigBean);//重新给JobDetail中的数据赋值 scheduler.rescheduleJob(triggerKey, trigger);//修改
logger.debug("{}...........................运行任务修改成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
} catch (SchedulerException e) {
b=false;
e.printStackTrace();
logger.info("{}...........................运行任务修改失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
}
return b;
} /**
* 移除一个运行任务
* @param interfaceConfigBean 接口对象
* @param scheduler 调度对象
* @return 成功返回true,异常返回false
*/
public Boolean removeJob(DbInterfaceConfigBeanWithBLOBs interfaceConfigBean,Scheduler scheduler){
Boolean b=true;
try {
TriggerKey triggerKey = TriggerKey.triggerKey(interfaceConfigBean.getInterfaceConfigId());// 根据id得到触发器名
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(JobKey.jobKey(interfaceConfigBean.getInterfaceCode()));//删除任务
logger.debug("{}...........................运行任务移除成功",interfaceConfigBean.getInterfaceCode());// 输出日志信息
} catch (SchedulerException e) {
b=false;
e.printStackTrace();
logger.info("{}...........................运行任务移除失败",interfaceConfigBean.getInterfaceCode());// 输出日志信息
}
return b;
} /**
* @param scheduler 调度对象
* 移除所有任务
*/
public void shutdownJobs(Scheduler scheduler) {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

QuartzManagerService

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

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

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

Quartz动态添加定时任务执行sql(服务启动添加+手动添加)的相关教程结束。

《Quartz动态添加定时任务执行sql(服务启动添加+手动添加).doc》

下载本文的Word格式文档,以方便收藏与打印。