Quartz 介绍
Quartz 定时任务可分为Trigger(触发器)、Job(任务)和Scheduler(调度器),定时任务的逻辑大体为:创建触发器和任务,并将其加入到调度器中,如下图所示:
Trigger 有五种触发器:
SimpleTrigger 触发器:需要在特定的日期/时间启动,且以指定的间隔时间(单位毫秒)重复执行 n 次任务,如 :在 9:00 开始,每隔1小时,每隔几分钟,每隔几秒钟执行一次 。没办法指定每隔一个月执行一次(每月的时间间隔不是固定值)。
CalendarIntervalTrigger 触发器:指定从某一个时间开始,以一定的时间间隔(单位有秒,分钟,小时,天,月,年,星期)执行的任务。
DailyTimeIntervalTrigger 触发器:指定每天的某个时间段内,以一定的时间间隔执行任务。并且支持指定星期。如:指定每天 9:00 至 18:00 ,每隔 70 秒执行一次,并且只要周一至周五执行。
CronTrigger 触发器:基于日历的任务调度器,即指定星期、日期的某时间执行任务。
NthIncludedDayTrigger 触发器:不同时间间隔的第 n 天执行任务。比如,在每个月的第 15 日处理财务发票记帐,同样设定双休日或者假期。
引入quartz依赖
<!--定时器-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
TaskScheduler类:
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;@Data
public class TaskScheduler {private String jobName;private String jobGroupName;private String state;private String jobClass;private String intervalUnit;private String intervalUnitName;private Integer timeInterval;private String cronExpression;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private Date startTime;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private Date endTime;private String description;
}
JobQuery类(查询用):
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
public class JobQuery {@ApiModelProperty(value = "模糊查询任务描述")private String jobNameLike;}
TaskSchedulerController类:
import com.example.demo.system.domain.Result;
import com.example.demo.system.job.JobQuery;
import com.example.demo.system.job.TaskScheduler;
import com.example.demo.system.service.ITaskSchedulerService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;@RestController
@Api(value = "system/taskScheduler", tags = "定时任务")
@RequestMapping("taskScheduler")
public class TaskSchedulerController {@Resourceprivate ITaskSchedulerService schedulerService;/*** 添加定时任务信息** @param taskScheduler 定时任务信息* @return ReturnModel 添加定时任务*/@PostMapping(value = "save")public Result<String> save(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName":"bookTask2",
// "description":"书籍定时任务",
// "jobTypeRadio":"expression",
// "startTime":"2024-01-12 15:20:00",
// "endTime":"2024-01-13 00:00:00",
// "jobClass":"com.example.demo.system.controller.BookTask",
// "cronExpression":"*/30 * * * * ?"
// }schedulerService.save(taskScheduler);return Result.success(taskScheduler.getJobName());}/*** 移除定时任务** @param taskScheduler 定时任务信息* @return ReturnModel 移除定时任务*/@PostMapping(value = "/delete")public Result<String> delete(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName": "bookTask"
// }schedulerService.delete(taskScheduler.getJobName());return Result.success(taskScheduler.getJobName());}/*** 修改定时任务** @param taskScheduler 定时任务信息* @return ReturnModel 修改定时任务*/@PostMapping(value = "update")public Result<String> update(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName":"bookTask",
// "description":"1",
// "jobTypeRadio":"expression",
// "startTime":"2024-01-13 14:00:00",
// "endTime":"",
// "jobClass":"com.example.demo.system.controller.BookTask",
// "cronExpression":"*/30 * * * * ?"
// }schedulerService.update(taskScheduler);return Result.success(taskScheduler.getJobName());}/*** 暂停定时任务** @param taskScheduler 定时任务名称* @return ReturnModel 暂停定时任务*/@PostMapping(value = "pause")public Result<String> pause(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName": "bookTask2"
// }schedulerService.pause(taskScheduler.getJobName());return Result.success(taskScheduler.getJobName());}/*** 恢复定时任务** @param taskScheduler 定时任务名称* @return ReturnModel 恢复定时任务*/@PostMapping(value = "resume")public Result<String> resume(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName": "bookTask2"
// }schedulerService.resume(taskScheduler.getJobName());return Result.success(taskScheduler.getJobName());}/*** 执行定时任务** @param taskScheduler 定时任务名称* @return ReturnModel 执行定时任务*/@PostMapping(value = "executeJob")public Result<String> executeJob(@RequestBody TaskScheduler taskScheduler) {
// {
// "jobName": "bookTask2"
// }schedulerService.executeJob(taskScheduler.getJobName());return Result.success(taskScheduler.getJobName());}/*** 查询单个定时任务信息** @param jobName 任务名称* @return ReturnModel 查询单个定时任务信息*/@GetMapping(value = "selectByName")public Result<TaskScheduler> selectByName(@RequestParam("jobName") String jobName) {TaskScheduler taskScheduler = schedulerService.selectByName(jobName);return Result.success(taskScheduler);}/*** 查询定时任务列表** @param jobQuery 查询条件* @return ReturnModel 查询定时任务列表*/@PostMapping(value = "selectList")public Result<List<TaskScheduler>> selectList(@RequestBody JobQuery jobQuery) {
// {
// "jobNameLike": ""
// }List<TaskScheduler> taskSchedulers = schedulerService.selectList(jobQuery);return Result.success(taskSchedulers);}
}
ITaskSchedulerService接口:
import com.example.demo.system.job.JobQuery;
import com.example.demo.system.job.TaskScheduler;
import java.util.List;public interface ITaskSchedulerService {/*** 添加定时任务信息** @param taskScheduler 定时任务信息*/void save(TaskScheduler taskScheduler);/*** 移除定时任务--根据任务名称移除** @param jobName 任务名*/void delete(String jobName);/*** 移除定时任务** @param groupName 组名* @param jobName 任务名*/void delete(String jobName, String groupName);/*** 修改定时任务** @param taskScheduler 任务信息*/void update(TaskScheduler taskScheduler);/*** 添加任务** @param jobName 任务名* @return 任务信息*/TaskScheduler selectByName(String jobName);/*** 查询单个定时任务信息** @param groupName 组名称* @param jobName 任务名称* @return 查询结果*/TaskScheduler selectByName(String jobName, String groupName);/*** 查询定时任务列表** @param jobQuery 查询条件* @return 查询结果*/List<TaskScheduler> selectList(JobQuery jobQuery);/*** 暂停定时任务** @param jobName 任务名*/void pause(String jobName);/*** 暂停定时任务** @param jobName 任务名* @param groupName 组名*/void pause(String jobName, String groupName);/*** 恢复定时任务** @param jobName 任务名*/void resume(String jobName);/*** 恢复定时任务** @param jobName 任务名* @param groupName 组名*/void resume(String jobName, String groupName);/*** 执行定时任务** @param jobName 任务名*/void executeJob(String jobName);/*** 执行定时任务** @param jobName 任务名* @param groupName 组名*/void executeJob(String jobName, String groupName);
}
TaskSchedulerServiceImpl实现类:
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo.system.job.JobQuery;
import com.example.demo.system.job.TaskScheduler;
import com.example.demo.system.service.ITaskSchedulerService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CalendarIntervalTriggerImpl;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;@Service
@Slf4j
public class TaskSchedulerServiceImpl implements ITaskSchedulerService {@Resourceprivate Scheduler scheduler;@Override@SneakyThrowspublic void save(TaskScheduler taskScheduler) {Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(taskScheduler.getJobClass());String jobName = taskScheduler.getJobName();String jobGroupName = StrUtil.isEmpty(taskScheduler.getJobGroupName()) ? Scheduler.DEFAULT_GROUP : taskScheduler.getJobGroupName();String triggerGroupName = StrUtil.isEmpty(taskScheduler.getJobGroupName()) ? Scheduler.DEFAULT_GROUP : taskScheduler.getJobGroupName();Date startTime = taskScheduler.getStartTime() == null ? new Date() : taskScheduler.getStartTime();Date endTime = taskScheduler.getEndTime();String description = StrUtil.isEmpty(taskScheduler.getDescription()) ? "" : taskScheduler.getDescription();JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).withDescription(description).build();if (taskScheduler.getCronExpression() != null && taskScheduler.getCronExpression().length() > 0) {Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, triggerGroupName).startAt(startTime).endAt(endTime).withSchedule(CronScheduleBuilder.cronSchedule(taskScheduler.getCronExpression()).withMisfireHandlingInstructionDoNothing()).build();scheduler.scheduleJob(jobDetail, trigger);} else {DateBuilder.IntervalUnit cycleUnit = DateBuilder.IntervalUnit.valueOf(taskScheduler.getIntervalUnit());Integer timeInterval = taskScheduler.getTimeInterval();Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, triggerGroupName).startAt(startTime).endAt(endTime).withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withInterval(timeInterval, cycleUnit).withMisfireHandlingInstructionDoNothing()).build();scheduler.scheduleJob(jobDetail, trigger);}}/*** 移除定时任务--根据任务名称移除*/@Overridepublic void delete(String jobName) {delete(jobName, Scheduler.DEFAULT_GROUP);}/*** 移除定时任务*/@Override@SneakyThrowspublic void delete(String jobName, String groupName) {groupName = StrUtil.isEmpty(groupName) ? Scheduler.DEFAULT_GROUP : groupName;JobKey jobKey = new JobKey(jobName, groupName);TriggerKey triggerKey = new TriggerKey(jobName, groupName);scheduler.pauseTrigger(triggerKey);scheduler.pauseJob(jobKey);// 移除触发器scheduler.unscheduleJob(triggerKey);// 删除任务scheduler.deleteJob(jobKey);}/*** 修改定时任务*/@Override@SneakyThrowspublic void update(TaskScheduler taskScheduler) {delete(taskScheduler.getJobName());save(taskScheduler);}/*** 查询单个定时任务*/@Override@SneakyThrowspublic TaskScheduler selectByName(String jobName, String groupName) {groupName = StrUtil.isEmpty(groupName) ? Scheduler.DEFAULT_GROUP : groupName;TaskScheduler taskScheduler = new TaskScheduler();JobKey jobKey = new JobKey(jobName, groupName);JobDetail jobDetail = scheduler.getJobDetail(jobKey);taskScheduler.setJobName(jobName);taskScheduler.setJobGroupName(groupName);setJob(jobKey, taskScheduler, jobDetail);return taskScheduler;}/*** 查询单个定时任务*/@Overridepublic TaskScheduler selectByName(String jobName) {return selectByName(jobName, Scheduler.DEFAULT_GROUP);}/*** 查询定时任务列表*/@Override@SneakyThrowspublic List<TaskScheduler> selectList(JobQuery jobQuery) {List<TaskScheduler> taskSchedulers = new ArrayList<>();GroupMatcher<JobKey> mathcher = GroupMatcher.anyJobGroup();String keyWord = jobQuery.getJobNameLike();Set<JobKey> jobKeys = scheduler.getJobKeys(mathcher);if (CollUtil.isEmpty(jobKeys)) {return new ArrayList<>();}for (JobKey jobKey : jobKeys) {if (StrUtil.isNotEmpty(keyWord) && !jobKey.getName().contains(keyWord)) {continue;}TaskScheduler taskScheduler = new TaskScheduler();JobDetail jobDetail = scheduler.getJobDetail(jobKey);taskScheduler.setJobName(jobKey.getName());taskScheduler.setJobGroupName(jobKey.getGroup());List<? extends Trigger> triggers = setJob(jobKey, taskScheduler, jobDetail);taskScheduler.setState(scheduler.getTriggerState(triggers.get(0).getKey()).name());taskSchedulers.add(taskScheduler);}return taskSchedulers;}private List<? extends Trigger> setJob(JobKey jobKey, TaskScheduler taskScheduler, JobDetail jobDetail) throws SchedulerException {taskScheduler.setJobClass(jobDetail.getJobClass().getName());taskScheduler.setDescription(jobDetail.getDescription());List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);Trigger trigger = triggers.get(0);taskScheduler.setStartTime(trigger.getStartTime());taskScheduler.setEndTime(trigger.getEndTime());if (trigger.getClass().equals(CronTriggerImpl.class)) {CronTriggerImpl cronTriggerImpl = (CronTriggerImpl) trigger;taskScheduler.setCronExpression(cronTriggerImpl.getCronExpression());}if (trigger.getClass().equals(CalendarIntervalTriggerImpl.class)) {CalendarIntervalTriggerImpl calendarIntervalTriggerImpl = (CalendarIntervalTriggerImpl) trigger;taskScheduler.setIntervalUnit(calendarIntervalTriggerImpl.getRepeatIntervalUnit().toString());taskScheduler.setTimeInterval(calendarIntervalTriggerImpl.getRepeatInterval());}return triggers;}/*** 暂停定时任务*/@Overridepublic void pause(String jobName) {pause(jobName, Scheduler.DEFAULT_GROUP);}/*** 暂停定时任务*/@Override@SneakyThrowspublic void pause(String jobName, String groupName) {groupName = StrUtil.isEmpty(groupName) ? Scheduler.DEFAULT_GROUP : groupName;TriggerKey triggerKey = new TriggerKey(jobName, groupName);scheduler.pauseTrigger(triggerKey);JobKey jobKey = new JobKey(jobName);scheduler.pauseJob(jobKey);}/*** 恢复定时任务*/@Overridepublic void resume(String jobName) {resume(jobName, Scheduler.DEFAULT_GROUP);}/*** 恢复定时任务*/@Override@SneakyThrowspublic void resume(String jobName, String groupName) {groupName = StrUtil.isEmpty(groupName) ? Scheduler.DEFAULT_GROUP : groupName;TriggerKey triggerKey = new TriggerKey(jobName, groupName);scheduler.resumeTrigger(triggerKey);JobKey jobKey = new JobKey(jobName);scheduler.resumeJob(jobKey);}/*** 执行定时任务*/@Overridepublic void executeJob(String jobName) {executeJob(jobName, Scheduler.DEFAULT_GROUP);}/*** 执行定时任务*/@Override@SneakyThrowspublic void executeJob(String jobName, String groupName) {groupName = StrUtil.isEmpty(groupName) ? Scheduler.DEFAULT_GROUP : groupName;JobKey jobKey = new JobKey(jobName, groupName);scheduler.triggerJob(jobKey);}
}
定时任务业务逻辑类BookTask:
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;@Slf4j
public class BookTask extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {log.info("book定时任务-开始执行:{}", DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}log.info("book定时任务-执行结束:{}", DateUtil.date().toString("yyyy-MM-dd HH:mm:ss"));}
}
以上动态配置定时任务需要的东西准备完毕,下一步就是配置
在此用swaggger来做测试
1、保存定时任务,我在此保存了两次 bookTask和bookTask2
注意:如果传了开始时间-startTime和结束时间-endTime,开始时间一定要小于结束时间,且开始时间要是一个未来时间,否则永远不会生效,也可以只传开始时间传结束时间。
2、看看列表
3、查看具体信息
4、更新定时任务:
5、删除定时任务
6、执行一次定时任务
7、暂停定时任务
8、恢复定时任务
9、持久化:在配置文件中加上该配置并新建数据表即可,重启项目后,配置的定时任务还在
spring:quartz:job-store-type: jdbcjdbc:initialize-schema: embedded
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_SIMPROP_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(200) NOT NULL, TRIGGER_GROUP VARCHAR(200) NOT NULL, STR_PROP_1 VARCHAR(512) NULL, STR_PROP_2 VARCHAR(512) NULL, STR_PROP_3 VARCHAR(512) NULL, INT_PROP_1 INT NULL, INT_PROP_2 INT NULL, LONG_PROP_1 BIGINT NULL, LONG_PROP_2 BIGINT NULL, DEC_PROP_1 NUMERIC(13,4) NULL, DEC_PROP_2 NUMERIC(13,4) NULL, BOOL_PROP_1 VARCHAR(1) NULL, BOOL_PROP_2 VARCHAR(1) NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB; CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB; CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB; CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB; CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB; CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); commit;
注意:如果有其他业务逻辑 ,需要在对应的方法里加业务代码