Spring Boot2.x整合Quartz 持久化数据库 页面管理job

一、Quartz的基本概念

    核心概念

    Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,void execute(JobExecutionContext context)  
    JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
    Trigger 触发器,指定何时触发任务。 
    Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

    Quartz集群架构

    一个Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点。这就意味着你必须对每个节点分别启动或停止。Quartz集群中,独立的Quartz节点并不与另一其的节点或是管理节点通信,而是通过相同的数据库表来感知到另一Quartz应用的。
 

二、Spring Boot整合Quartz
    Spring Boot2.x中提供了对Quartz的自动配置,并纳入了Spring容器中进行管理。
pom:

     <!--quartz依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <!--quartz依赖-->

数据库持久化表:

官网下载quartz jar包\docs\dbTables下。
文章结尾附带MySQL Quartz脚本
注意:Quartz中是通过sched_name、job_name 和 job_group来确定Job的唯一性的

yml:

spring:
  quartz:
    #相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            instanceName: clusteredScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            #集群设置
            isClustered: true
            clusterCheckinInterval: 10000
            useProperties: true
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            #设置守护线程  默认为true
            threadsInheritContextClassLoaderOfInitializingThread: true
    #数据库方式
    job-store-type: jdbc
    #初始化表结构
    #jdbc:
      #initialize-schema: never
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
  application:
    name: quartz-node-one

如果需要对Quartz的SchedulerFactoryBean进行配置,可以实现SchedulerFactoryBeanCustomizer来实现
Job:

继承QuartzJobBean,重写executeInternal方法,实现自己的业务逻辑。Job中可以直接注入Spring容器管理的Bean,如service
 

@Slf4j //此处为lomback注解 生成log对象
public class TestJob extends QuartzJobBean {

    @Autowired
    private UserService userService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info(userService.toString());
        log.info("执行定时任务------------"+System.currentTimeMillis());
    }
}

到此,整合完毕,下面接着写页面管理job。
注意:现在这个job是不完整的,因为没有配置jobdetil内容,我们将在后面的页面管理中进行配置

三、页面化管理

    自定义表
    注意:这张表和前面官网的表没有任何关系,和quartz的定时任务执行严格的讲也没有任何关系。这张表只是存储我们通过
    页面定义的一些job信息,然后再通过quartz的api将这些job放到quartz的持久化数据库中,也就是前面建的表中。
    quartz的任务调度用的是官网提供sql脚本中初始化的表,而不是我们现在自定义的表。

 

//这个表可自行定义
CREATE TABLE `sys_job` (
  `job_id` varchar(64) NOT NULL,
  `job_name` varchar(64) DEFAULT NULL,
  `job_group` varchar(64) DEFAULT NULL,
  `cron_expression` varchar(64) DEFAULT NULL,
  `job_status` varchar(64) DEFAULT NULL,
  `job_class` varchar(200) DEFAULT NULL,
  `prevfire_time` date DEFAULT NULL,
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


    自定义:QuartzManager类
    这个类可以直接当做工具类使用,包含了job的新增、删除、修改、暂停、重启、开启所有job、关闭所有job等方法

import com.txp.boot.quartz.model.entity.SysJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//让Spring管理这个Bean
@Component
@Slf4j
public class QuartzManager {

    //注入调度器
	@Autowired
	private  Scheduler scheduler;


	
	/**
	 * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
	 * 
	 * @param myJob
	 * 
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public  void addJob(SysJob myJob, Class cls) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:addJob  start");
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			if(scheduler==null){ log.info("scheduler is null");}
			CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			if (null == cronTrigger) {
				JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName,jobGroup).build();

				cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup)
						.withSchedule(CronScheduleBuilder.cronSchedule(myJob.getCronExpression())).build();
//						cronTrigger.getJobDataMap().put("jobEntity", myJob);
				
				scheduler.scheduleJob(jobDetail, cronTrigger);
				//启动一个定时器
				if (!scheduler.isShutdown()) {
					scheduler.start();
				}
			} else {
				cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(myJob.getCronExpression()))
						.build();
				scheduler.rescheduleJob(triggerKey, cronTrigger);
			}
			//等待启动完成
//			Thread.sleep(TimeUnit.SECONDS.toMillis(10));
		} catch (Exception e) {
			e.printStackTrace();
			log.info("定时任务启动失败:" + e.getMessage());
		} 
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:addJob  end");
	}

	/**
	 * @Description: 暂停一个任务
	 * 
	 * @param myJob
	 * 
	 */
	public  void pasueOneJob(SysJob myJob) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:pasueOneJob  start");
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			Trigger trigger = scheduler.getTrigger(triggerKey);
//			if(null==trigger){
//				log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
//				return;
//			}
			JobKey jobKey = trigger.getJobKey();
			scheduler.pauseJob(jobKey);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:pasueOneJob  end");
	}
	
	/**
	 * @Description: 重启一个任务
	 * 
	 * @param myJob
	 * 
	 */
	public  void resOneJob(SysJob myJob) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:resOneJob  start");
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			Trigger trigger = scheduler.getTrigger(triggerKey);
//			if(null==trigger){
//				log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
//				return;
//			}
			scheduler.rescheduleJob(triggerKey, trigger);
			
//			Thread.sleep(TimeUnit.MINUTES.toMillis(10));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:resOneJob  end");
	}

	/**
	 * @Description: 修改一个任务的触发时间
	 *
	 */
	public  void modifyJobTime(SysJob myJob, String time) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:modifyJobTime  start");
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			myJob.setCronExpression(time);
			CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(myJob.getCronExpression());
			cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder)
					.build();
			scheduler.rescheduleJob(triggerKey, cronTrigger);
			
//			Thread.sleep(TimeUnit.MINUTES.toMillis(60));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:modifyJobTime  end");
	}
	
	/**
	 * @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
	 *
	 * 
	 */
	public  void removeJob(SysJob myJob) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob  start");
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			Trigger trigger = scheduler.getTrigger(triggerKey);
			if(null==trigger){
				log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
				return;
			}
			JobKey jobKey = trigger.getJobKey();
			scheduler.pauseTrigger(triggerKey);// 停止触发器
			scheduler.unscheduleJob(triggerKey);// 移除触发器
			scheduler.deleteJob(jobKey);// 删除任务
			
			//Thread.sleep(TimeUnit.MINUTES.toMillis(10));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob  end");
	}

	/**
	 * 
	 * 方法表述  获得执行器状态
	 * @return
	 * String
	 */
	public  String getStatus(SysJob myJob){
		String state = "NONE";
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			//trigger state
			TriggerState triggerState = scheduler.getTriggerState(triggerKey);
			state = triggerState.toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return state;
	}
	
	/**
	 * 是否存在任务
	 * 方法表述
	 * @param myJob
	 * @return
	 * boolean
	 */
	public  boolean hasTrigger(SysJob myJob){
		boolean isHas = true;
		try {
			// 唯一主键
			String jobName = myJob.getJobName();
			String jobGroup = myJob.getJobGroup();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			Trigger trigger = scheduler.getTrigger(triggerKey);
			if(null==trigger){
				log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
				isHas = false;
			}
		} catch (SchedulerException e) {
			isHas = false;
			e.printStackTrace();
		}
		return isHas;
	}
	
	/**
	 * @Description:启动所有定时任务
	 * 
	 */
	public  void startJobs() {
		try {
			scheduler.start();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * @Description:关闭所有定时任务
	 * 
	 */
	public  void shutdownJobs() {
		try {
			if (!scheduler.isShutdown()) {
				scheduler.shutdown();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}

Controller层
controller中,可以直接注入我们前面定义的QuartzManager类

@Slf4j
@RestController
@RequestMapping("/sysJob")
public class SysJobController {

    //自动注入QuartzManager
    @Autowired
    private QuartzManager quartzManager;

    @Resource
    private SysJobService jobService; 
 
/**
* 页面访问方法的定义,这里是一个修改job的方法,具体逻辑自行定义
* 1.此处为省事,没有返回值
* 2.quartzManager.removeJob(t)  调用Quartz Api 从Quartz持久化的表中移除任务
* 3.jobService.updJob(job)      调用自定义的service 对自定义表sys_job进行更新操作
* 4.此处注释只是为了强调,页面化管理job只是管理自己创建表中job,想要更改Quartz持久化表中的Job, 
    必须调用Quartz的Api
*/
@PostMapping("editJob")
    public void editJob(SysJob job){
        try {
            if(job.getJobId()!=null && StringUtils.isNotBlank(job.getJobId().toString())){

                SysJob t = jobService.queryById(job.getJobId());
                if(null != t){
                    quartzManager.removeJob(t);
                }
                jobService.updJob(job);
               log.info("成功","修改成功");
            }else{
                job.setJobId(ToolsUtils.generatorUUID());
                jobService.addJob(job);
                log.info("成功","创建成功");
            }
            //新增或者重新添加job
            quartzManager.addJob(job,Class.forName(job.getJobClass()));
        } catch (Exception e) {
            log.info("失败","修改失败");
        }
    }
}

Service/Dao层
笔者用的是mybatis-plus做的数据层访问,基础的增删改查,这里不再粘贴代码
MockMvc测试
 

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest
public class QuartzDemoApplicationTest {
    /**
     * 模拟mvc测试对象
     */
    private MockMvc mockMvc;

    /**
     * web项目上下文
     */
    @Autowired
    private WebApplicationContext webApplicationContext;

    /**
     * 所有测试方法执行之前执行该方法
     */
    @Before
    public void before() {
        //获取mockmvc对象实例
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    /**
     * 测试通过web添加一个job,这里调用的是editjob接口
     * @throws Exception
     */
    @Test
    public void addGood() throws Exception
    {
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/sysJob/editJob")
                .param("jobName","job_test")
                .param("jobGroup","tes_group")
                .param("jobStatus","1")
                .param("jobClass","com.txp.boot.quartz.timers.job.TestJob")
                .param("cronExpression","0/5 * * * * ?")
        )
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().is(200))
                .andReturn();
        result.getResponse().setCharacterEncoding("UTF-8");
        System.out.println(result.getResponse().getContentAsString());
    }
}

代码运行步骤:
   1.先运行测试类,添加一个job
   2.启动Spring主启动类,就可以在控制台看到定时任务的执行了

 

以上就是spring boot整合Quartz 并实现页面化控制的一个demo,如有错误或者不足,还请指正。再啰嗦一句,页面化控制是操作的我们自己定义的job表,实际操作Quartz还是调用Quartz的类库。

MySQL 数据库脚本

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(190) NOT NULL,
JOB_GROUP VARCHAR(190) 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(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) 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(190) 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(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) 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(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) 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(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) 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(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) 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(190) 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(190) 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(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
INSTANCE_NAME VARCHAR(190) 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(190) NULL,
JOB_GROUP VARCHAR(190) 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(190) 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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值