【QUARTZ】springboot+quartz动态配置定时任务

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;

注意:如果有其他业务逻辑 ,需要在对应的方法里加业务代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/344488.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CMake+大漠插件的应用开发——处理dm.dll,免注册调用大漠插件

文章目录 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件说明环境项目结构配置编译环境编码-直接调用 dll编码-生成tlh文件&#xff0c;便于提示 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件 说明 网上有一种使用方式是&am…

Playwright 结合 Selenium Grid - 1.windows 环境使用教程

Playwright 可以连接到运行 Selenium 4 的 Selenium Grid Hub 来启动 Google Chrome 或 Microsoft Edge 浏览器,而不是在本地机器上运行浏览器。 下载Selenium Grid 打开selenium官方https://www.selenium.dev/downloads/下载Selenium Server (Grid) 目前最新版本4.16.1 下…

Windows 项目从0到1的部署

目录 一. 安装jdk 1.1 安装jdk 1.2 配置jdk的环境配置jdk 1.3 配置成功 二. 配置tomcat 2.1 启动tomcat 2.2 防火墙设置 三. 安装MySQL 3.1 安装步骤 3.2 内部连接 3.3 外部连接 四. 部署项目 4.1 项目部署 4.2 修改mysql的用户密码 一. 安装jdk 这里给大家准备好了jdk和…

数据库SELECT语句

文章目录 一、检索数据二、排序检索三、过滤数据四、数据过滤4.1 组合WHERE子句1. AND操作符2. OR操作符3. 计算次序 4.2 IN操作符4.3 NOT操作符 五、用通配符过滤LIKE操作符1. 百分号&#xff08;%&#xff09;通配符2. 下划线&#xff08;_&#xff09;通配符 使用通配符的技…

what is BERT?

BERT Introduction Paper 参考博客 9781838821593_ColorImages.pdf (packt-cdn.com) Bidirectional Encoder Representation from Transformer 来自Transformer的双向编码器表征 基于上下文&#xff08;context-based&#xff09;的嵌入模型。 那么基于上下文&#xff08;…

apache、nginx、php 隐藏版本号

apache、nginx、php 隐藏版本号 针对的系统都是CentOS 1、没配置之前 1.1 Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.2.24 mod_wsgi/3.4 Python/2.7.5 1.2 Server: nginx/1.16.0 1.3 X-Powered-By&#xff1a;7.2.24 2、配置信息 不知道具体位置&#xff0c;可…

小程序系列-5.WXML 模板语法

一、数据绑定 1、在 data 中定义页面的数据 动态绑定内容&#xff1a; 动态绑定属性&#xff1a; 2. Mustache 语法的格式 3. Mustache 语法的应用场景 4. 三元运算 5.算数运算 二、 事件绑定 1. 什么是事件&#xff1f; 2. 小程序中常用的事件 3. 事件对象的属性列表 4.…

【Java SE语法篇】6.数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1.数组的基本概念1.1 为什么使用数组&#xff1f;1.…

【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C考前速过系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《…

easyexcel上传校验的方法封装

easyexcel版本3.1.5 使用自定义注解的方式来定义校验的类型&#xff0c;避免冗余代码。 //校验value不能为空&#xff0c;且长度最大为30 RowCheck(value {RowCheckType.EMPTY,RowCheckType.LENGTH},max 30) private String value; 具体代码&#xff1a; 首先定义校验类型…

缓存学习实战篇

缓存练习题&#xff08;用户查询操作&#xff09; public List<ShopType> queryAllType() throws JsonProcessingException {//从缓存中查数据String shopTypeJson stringRedisTemplate.opsForValue().get("cache:shopType");//如果缓存命中&#xff0c;if (S…

短视频账号矩阵剪辑分发系统无人直播技术开发源头

一、全行业独家源头最全面的核心技术 短视频矩阵新玩法是指利用批量自动混剪系统来处理大量短视频&#xff0c;通过智能算法自动进行视频剪辑、场景切换、特效添加等操作&#xff0c;最终生成高质量、精彩纷呈的混剪视频作品的方法和技术。这一方法的出现使得大规模短视频制作…