技术的进阶往往始于对工具边界的探索。在初识SpringBoot定时任务时,我们习惯于用
@Scheduled
快速实现基础调度,但当面对动态规则变更、多任务协同、故障恢复等真实场景时,这种简单方案却显得捉襟见肘。
依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.39</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
</dependencies>
properties配置
# Spring Datasource
spring.datasource.url=jdbc:mysql://192.168.10.182:13306/quartz?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Spring Quartz
spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-scheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.isClustered=false
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.threadPool.threadCount=10
# Mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.quartzdemo.entity
配置类
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.annotation.Resource;
@Configuration
public class QuartzConfig {
@Resource
private SchedulerFactoryBean schedulerFactoryBean;
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean.getScheduler();
}
}
创建执行器
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import org.quartz.*;
import java.util.Date;
public class ConcurrentExecutor implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 获取触发器信息
Trigger trigger = context.getTrigger();
Date startTime = trigger.getStartTime();
Date endTime = trigger.getEndTime();
System.out.println("startTime:" + DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss") + " endTime:" + DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"));
Date previousFireTime = trigger.getPreviousFireTime();
Date nextFireTime = trigger.getNextFireTime();
System.out.println("previousFireTime:" + DateUtil.format(previousFireTime, "yyyy-MM-dd HH:mm:ss") + " nextFireTime:" + DateUtil.format(nextFireTime, "yyyy-MM-dd HH:mm:ss"));
// 获取JobDetail信息
JobDetail jobDetail = context.getJobDetail();
// 获取JobDataMap信息
JobDataMap jobDataMap = jobDetail.getJobDataMap();
System.out.println("jobDataMap:" + JSON.toJSONString(jobDataMap));
}
}
实体类
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class InspectionJob implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 任务类型
*/
private Integer jobType;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务状态
*/
private Integer jobStatus;
/**
* cron表达式
*/
private String cronExpression;
/**
* 任务执行类
*/
private String clazzName;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private String createBy;
/**
* 更新时间
*/
private Date updateTime;
/**
* 更新人
*/
private String updateBy;
/**
* 删除标志
*/
private Integer deleted;
}
入参实体
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
@Data
public class InspectionJobDto implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 任务类型
*/
private Integer jobType;
/**
* 任务名称
*/
private String jobName;
/**
* cron表达式
*/
private String cronExpression;
/**
* 任务执行类
*/
private String clazzName;
/**
* 任务数据
*/
private Map<String,Object> params;
}
数据库操作
import com.example.quartzdemo.entity.InspectionJob;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface InspectionJobMapper {
/**
* 添加任务
*
* @param data
* @return
*/
int addJob(InspectionJob data);
/**
* 更新任务
*
* @param data
* @return
*/
int updateJob(InspectionJob data);
/**
* 删除任务
*
* @param data
* @return
*/
int deleteJob(InspectionJob data);
/**
* 获取任务
*
* @param data
* @return
*/
InspectionJob getJob(InspectionJob data);
/**
* 获取所有任务
*
* @param data
* @return
*/
List<InspectionJob> getAllJob(InspectionJob data);
}
数据库操作xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.quartzdemo.mapper.InspectionJobMapper">
<resultMap id="BaseResultMap" type="com.example.quartzdemo.entity.InspectionJob">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="jobName" column="job_name"/>
<result property="jobType" column="job_type"/>
<result property="cronExpression" column="cron_expression"/>
<result property="clazzName" column="clazz_name"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="jobStatus" column="job_status"/>
<result property="deleted" column="deleted"/>
</resultMap>
<sql id="Base_Column_List">
id,
job_name,
job_type,
cron_expression,
clazz_name,
create_time,
update_time,
create_by,
update_by,
job_status,
deleted
</sql>
<insert id="addJob" parameterType="com.example.quartzdemo.entity.InspectionJob" useGeneratedKeys="true" keyProperty="id">
insert into inspection_job
(
job_name,
job_type,
cron_expression,
clazz_name,
create_time,
update_time,
create_by,
update_by,
job_status
)
values
(
#{jobName},
#{jobType},
#{cronExpression},
#{clazzName},
now(),
now(),
#{createBy},
#{updateBy},
#{jobStatus}
)
</insert>
<update id="updateJob" parameterType="com.example.quartzdemo.entity.InspectionJob">
update inspection_job
<set>
<if test="jobName != null">
job_name = #{jobName},
</if>
<if test="jobType != null">
job_type = #{jobType},
</if>
<if test="cronExpression != null">
cron_expression = #{cronExpression},
</if>
<if test="clazzName != null">
clazz_name = #{clazzName},
</if>
<if test="jobStatus != null">
job_status = #{jobStatus},
</if>
<if test="createTime != null">
create_time = #{createTime},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="createBy != null">
create_by = #{createBy},
</if>
<if test="updateBy != null">
update_by = #{updateBy},
</if>
</set>
where deleted = 0 AND id = #{id}
</update>
<delete id="deleteJob" parameterType="com.example.quartzdemo.entity.InspectionJob">
update inspection_job
set deleted = 1,
update_time = now(),
update_by = #{updateBy}
where deleted = 0 AND id = #{id}
</delete>
<select id="getJob" parameterType="com.example.quartzdemo.entity.InspectionJob" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from inspection_job
where deleted = 0 AND id = #{id}
</select>
<select id="getAllJob" parameterType="com.example.quartzdemo.entity.InspectionJob" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from inspection_job
where deleted = 0
</select>
</mapper>
任务服务接口
import com.example.quartzdemo.entity.InspectionJob;
import com.example.quartzdemo.entity.InspectionJobDto;
import java.util.List;
public interface InspectionJobService {
/**
* 添加定时任务Job
*
*/
void addJob(InspectionJobDto dto);
/**
* 立即执行一次定时任务
*
*/
void executeOnce(InspectionJobDto dto);
/**
* 暂停定时任务
*
*/
void pauseJob(InspectionJobDto dto);
/**
* 恢复定时任务
*
*/
void resumeJob(InspectionJobDto dto);
/**
* 更新定时任务
*
*/
void updateJob(InspectionJobDto dto);
/**
* 删除定时任务
*
*/
void deleteJob(InspectionJobDto dto);
/**
* 获取所有的定时任务*
* @return 定时任务列表
*/
List<InspectionJob> getAllJob();
}
任务服务实现
import com.example.quartzdemo.constant.QuartzConstant;
import com.example.quartzdemo.constant.QuartzCron;
import com.example.quartzdemo.constant.QuartzJobStatus;
import com.example.quartzdemo.entity.InspectionJob;
import com.example.quartzdemo.entity.InspectionJobDto;
import com.example.quartzdemo.executor.ConcurrentExecutor;
import com.example.quartzdemo.mapper.InspectionJobMapper;
import com.example.quartzdemo.service.InspectionJobService;
import lombok.RequiredArgsConstructor;
import org.quartz.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class InspectionJobServiceImpl implements InspectionJobService {
private final InspectionJobMapper inspectionJobMapper;
private final Scheduler scheduler;
@Override
public void addJob(InspectionJobDto dto) {
InspectionJob inspectionJob = new InspectionJob();
BeanUtils.copyProperties(dto, inspectionJob);
inspectionJob.setJobStatus(QuartzJobStatus.RUNNING.getCode());
inspectionJobMapper.addJob(inspectionJob);
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, inspectionJob.getId()), QuartzConstant.JOB_GROUP);
try {
Integer jobType = inspectionJob.getJobType();
QuartzCron quartzCron = QuartzCron.getCron(jobType);
Map<String, Object> params = dto.getParams();
JobBuilder jobBuilder = JobBuilder.newJob(quartzCron.getClazz());
if (params != null){
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.putAll(params);
jobBuilder.usingJobData(jobDataMap);
}
jobBuilder.withIdentity(jobKey);
JobDetail jobDetail = jobBuilder.build();
TriggerKey triggerKey = TriggerKey.triggerKey(String.format("%s_%s", QuartzConstant.TRIGGER_NAME, inspectionJob.getId()), QuartzConstant.TRIGGER_GROUP);
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(triggerKey);
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(quartzCron.getCron()));
triggerBuilder.startNow();
Trigger trigger = triggerBuilder.build();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("任务创建失败");
}
}
@Override
public void executeOnce(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("执行一次失败");
}
}
@Override
public void pauseJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.pauseJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setJobStatus(QuartzJobStatus.PAUSED.getCode());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.updateJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("暂停任务失败");
}
}
@Override
public void resumeJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.resumeJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setJobStatus(QuartzJobStatus.RUNNING.getCode());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.updateJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("恢复任务失败");
}
}
@Override
public void updateJob(InspectionJobDto dto) {
}
@Override
public void deleteJob(InspectionJobDto dto) {
try {
JobKey jobKey = new JobKey(String.format("%s_%s", QuartzConstant.JOB_NAME, dto.getId()), QuartzConstant.JOB_GROUP);
scheduler.deleteJob(jobKey);
InspectionJob inspectionJob = new InspectionJob();
inspectionJob.setId(dto.getId());
inspectionJob.setUpdateBy("test");
inspectionJob.setUpdateTime(new Date());
inspectionJobMapper.deleteJob(inspectionJob);
} catch (SchedulerException e) {
e.printStackTrace();
throw new RuntimeException("删除任务失败");
}
}
@Override
public List<InspectionJob> getAllJob() {
return null;
}
}
常量信息
public interface QuartzConstant {
String JOB_NAME = "jobName";
String JOB_GROUP = "jobGroup";
String TRIGGER_NAME = "triggerName";
String TRIGGER_GROUP = "triggerGroup";
}
import com.example.quartzdemo.executor.ConcurrentExecutor;
import lombok.Getter;
import org.quartz.Job;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum QuartzCron {
/**
* 一年一次
*/
YEARLY(0,"0 0 0 1 1 ? *",ConcurrentExecutor.class),
/**
* 每季度一次
*/
QUARTERLY(1,"0 0 0 1 1/3 ? *",ConcurrentExecutor.class),
/**
* 每月一次
*/
MONTHLY(2,"0 0 0 1 * ? *",ConcurrentExecutor.class),
/**
* 每周一次
*/
WEEKLY(3,"0 0 0 ? * 1 *",ConcurrentExecutor.class),
/**
* 每日一次
*/
DAILY(4,"0 0 0 * * ? *",ConcurrentExecutor.class),
/**
* 每小时一次
*/
HOURLY(5,"0 0 0/1 * * ? *",ConcurrentExecutor.class),
/**
* 每分钟一次
*/
MINUTE(6,"0 0/1 * * * ? *", ConcurrentExecutor.class);
/**
* 枚举值
*/
private final Integer code;
/**
* 描述
*/
private final String cron;
/**
* 执行器
*/
private final Class<? extends Job> clazz;
private static final Map<Integer,QuartzCron> cronMap = new HashMap<>(7);
QuartzCron(Integer code, String cron,Class<? extends Job> clazz) {
this.code = code;
this.cron = cron;
this.clazz = clazz;
}
static {
for (QuartzCron quartzCron : QuartzCron.values()) {
cronMap.put(quartzCron.getCode(),quartzCron);
}
}
public static QuartzCron getCron(Integer code) {
return cronMap.get(code);
}
}
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum QuartzJobStatus {
NORMAL(0,"待执行"),
RUNNING(1,"运行中"),
PAUSED(2,"已暂停"),
COMPLETE(3,"已完成"),
;
private final Integer code;
private final String desc;
private static final Map<Integer,QuartzJobStatus> statusMap = new HashMap<>(5);
static {
for (QuartzJobStatus status : QuartzJobStatus.values()) {
statusMap.put(status.getCode(),status);
}
}
QuartzJobStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}
Controller层
import com.example.quartzdemo.entity.InspectionJobDto;
import com.example.quartzdemo.service.InspectionJobService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@RequestMapping("/job")
public class InspectionJobController {
private final InspectionJobService inspectionJobService;
@PostMapping("/add")
public void addJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.addJob(dto);
}
@PostMapping("/executeOnce")
public void executeOnce(@RequestBody InspectionJobDto dto)
{
inspectionJobService.executeOnce(dto);
}
@PostMapping("/pause")
public void pauseJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.pauseJob(dto);
}
@PostMapping("/resume")
public void resumeJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.resumeJob(dto);
}
@PostMapping("/update")
public void updateJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.updateJob(dto);
}
@PostMapping("/delete")
public void deleteJob(@RequestBody InspectionJobDto dto)
{
inspectionJobService.deleteJob(dto);
}
@PostMapping("/getAll")
public Object getAllJob()
{
return inspectionJobService.getAllJob();
}
}
表结构
-- ----------------------------
-- Table structure for inspection_job
-- ----------------------------
DROP TABLE IF EXISTS `inspection_job`;
CREATE TABLE `inspection_job` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`job_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`job_type` int NULL DEFAULT NULL COMMENT '任务类型(0:一年一次,1:一季度一次,2:一月一次,3:一周一次)',
`cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'cron表达式',
`clazz_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '执行器全路径名',
`city_id` bigint NULL DEFAULT NULL,
`district_id` bigint NULL DEFAULT NULL,
`street_id` bigint NULL DEFAULT NULL,
`job_status` int NULL DEFAULT NULL COMMENT '任务状态(0:待执行,1:运行中,2:已暂停,3:已完成)',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
`create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`deleted` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_BLOB_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`BLOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `SCHED_NAME`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_CALENDARS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
CREATE TABLE `QRTZ_CALENDARS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CALENDAR_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CALENDAR` blob NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_CRON_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
CREATE TABLE `QRTZ_CRON_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`CRON_EXPRESSION` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TIME_ZONE_ID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `QRTZ_CRON_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_FIRED_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`ENTRY_ID` varchar(95) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`INSTANCE_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`FIRED_TIME` bigint NOT NULL,
`SCHED_TIME` bigint NOT NULL,
`PRIORITY` int NOT NULL,
`STATE` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `ENTRY_ID`) USING BTREE,
INDEX `IDX_QRTZ_FT_TRIG_INST_NAME`(`SCHED_NAME` ASC, `INSTANCE_NAME` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME` ASC, `INSTANCE_NAME` ASC, `REQUESTS_RECOVERY` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_J_G`(`SCHED_NAME` ASC, `JOB_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_JG`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_T_G`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_FT_TG`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_JOB_DETAILS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
CREATE TABLE `QRTZ_JOB_DETAILS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`JOB_CLASS_NAME` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_DURABLE` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`IS_UPDATE_DATA` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_J_REQ_RECOVERY`(`SCHED_NAME` ASC, `REQUESTS_RECOVERY` ASC) USING BTREE,
INDEX `IDX_QRTZ_J_GRP`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_LOCKS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_LOCKS`;
CREATE TABLE `QRTZ_LOCKS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`LOCK_NAME` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `LOCK_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_PAUSED_TRIGGER_GRPS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_SCHEDULER_STATE
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
CREATE TABLE `QRTZ_SCHEDULER_STATE` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`INSTANCE_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`LAST_CHECKIN_TIME` bigint NOT NULL,
`CHECKIN_INTERVAL` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_SIMPLE_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`REPEAT_COUNT` bigint NOT NULL,
`REPEAT_INTERVAL` bigint NOT NULL,
`TIMES_TRIGGERED` bigint NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `QRTZ_SIMPLE_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_SIMPROP_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`STR_PROP_1` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`STR_PROP_2` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`STR_PROP_3` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`INT_PROP_1` int NULL DEFAULT NULL,
`INT_PROP_2` int NULL DEFAULT NULL,
`LONG_PROP_1` bigint NULL DEFAULT NULL,
`LONG_PROP_2` bigint NULL DEFAULT NULL,
`DEC_PROP_1` decimal(13, 4) NULL DEFAULT NULL,
`DEC_PROP_2` decimal(13, 4) NULL DEFAULT NULL,
`BOOL_PROP_1` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`BOOL_PROP_2` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for QRTZ_TRIGGERS
-- ----------------------------
DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
CREATE TABLE `QRTZ_TRIGGERS` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`JOB_GROUP` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`NEXT_FIRE_TIME` bigint NULL DEFAULT NULL,
`PREV_FIRE_TIME` bigint NULL DEFAULT NULL,
`PRIORITY` int NULL DEFAULT NULL,
`TRIGGER_STATE` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`TRIGGER_TYPE` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`START_TIME` bigint NOT NULL,
`END_TIME` bigint NULL DEFAULT NULL,
`CALENDAR_NAME` varchar(190) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`MISFIRE_INSTR` smallint NULL DEFAULT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_J`(`SCHED_NAME` ASC, `JOB_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_JG`(`SCHED_NAME` ASC, `JOB_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_C`(`SCHED_NAME` ASC, `CALENDAR_NAME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_G`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_STATE`(`SCHED_NAME` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_N_STATE`(`SCHED_NAME` ASC, `TRIGGER_NAME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_N_G_STATE`(`SCHED_NAME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NEXT_FIRE_TIME`(`SCHED_NAME` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST`(`SCHED_NAME` ASC, `TRIGGER_STATE` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_MISFIRE`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC, `TRIGGER_STATE` ASC) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME` ASC, `MISFIRE_INSTR` ASC, `NEXT_FIRE_TIME` ASC, `TRIGGER_GROUP` ASC, `TRIGGER_STATE` ASC) USING BTREE,
CONSTRAINT `QRTZ_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;