博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
精通SpringBoot——第十篇:使用Quartz实现动态配置定时任务
阅读量:7154 次
发布时间:2019-06-29

本文共 25627 字,大约阅读时间需要 85 分钟。

定时任务简述

定时任务,在企业开发中尤其重要,很多业务都是需要定时任务去做的。比如说10点开售某件东西,凌晨0点统计注册人数,统计其他各种等等。这个时候不可能说让人为的去开启某个开关或者怎么怎么样的,如果这样的话,估计都要崩溃了。今天给大家介绍如何在项目中使用Quartz并且在后台动态配置定时任务的启动,暂停,重启,停止,还有修改启动的时间,修改执行的任务等。

引入依赖的jar包

org.springframework.boot
spring-boot-starter-quartz
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mysql
mysql-connector-java
runtime

application.yml的配置

quartz:    scheduler:      instance-name: MyselfScheduler      instance-id: NON_CLUSTERED # 使用集群:AUTO 不使用集群:NON_CLUSTERED      skip-update-check: true      job-factory:        class: org.quartz.simpl.SimpleJobFactory    job-store:      class: org.quartz.impl.jdbcjobstore.JobStoreTX      driver-delegate-class: org.quartz.impl.jdbcjobstore.StdJDBCDelegate      datasource: quartzDataSource      table-prefix: QRTZ_      is-clustered: true    thread-pool:      class: org.quartz.simpl.SimpleThreadPool      thread-count: 5    datasource:      quartzDataSource:        driver: ${spring.datasource.druid.driver-class-name}        url: ${spring.datasource.druid.url}        user: ${spring.datasource.druid.username}        password: ${spring.datasource.druid.password}        maxConnections: 5        validationQuery: select 0        connection-provider:          class: com.lingdu.welend.config.quartz.DruidConnectionProvider

扩展druid数据源作为quartz的数据源

import com.alibaba.druid.pool.DruidDataSource;import org.quartz.SchedulerException;import org.quartz.utils.ConnectionProvider;import java.sql.Connection;import java.sql.SQLException;/** * @author Lee * @// TODO 2018/6/1-16:37 * @description Druid连接池的Quartz扩展类 */public class DruidConnectionProvider implements ConnectionProvider {    /*    * 常量配置,与quartz.properties文件的key保持一致(去掉前缀),同时提供set方法,Quartz框架自动注入值。    */    //JDBC驱动    public String driver;    //JDBC连接串    public String URL;    //数据库用户名    public String user;    //数据库用户密码    public String password;    //数据库最大连接数    public int maxConnections;    //数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。    public String validationQuery;    private boolean validateOnCheckout;    private int idleConnectionValidationSeconds;    public String maxCachedStatementsPerConnection;    private String discardIdleConnectionsSeconds;    public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;    public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;    //Druid连接池    private DruidDataSource datasource;    /*    * 接口实现    */    public Connection getConnection() throws SQLException {        return datasource.getConnection();    }    public void shutdown() throws SQLException {        datasource.close();    }    public void initialize() throws SQLException {        if (this.URL == null) {            throw new SQLException("DBPool could not be created: DB URL cannot be null");        }        if (this.driver == null) {            throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");        }        if (this.maxConnections < 0) {            throw new SQLException("DBPool maxConnectins could not be created: Max connections must be greater than zero!");        }        datasource = new DruidDataSource();        try {            datasource.setDriverClassName(this.driver);        } catch (Exception e) {            try {                throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);            } catch (SchedulerException e1) {            }        }        datasource.setUrl(this.URL);        datasource.setUsername(this.user);        datasource.setPassword(this.password);        datasource.setMaxActive(this.maxConnections);        datasource.setMinIdle(1);        datasource.setMaxWait(0);        datasource.setMaxPoolPreparedStatementPerConnectionSize(DEFAULT_DB_MAX_CONNECTIONS);        if (this.validationQuery != null) {            datasource.setValidationQuery(this.validationQuery);            if (!this.validateOnCheckout)                datasource.setTestOnReturn(true);            else                datasource.setTestOnBorrow(true);            datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);        }    }    /*    * 提供get set方法    */    public String getDriver() {        return driver;    }    public void setDriver(String driver) {        this.driver = driver;    }    public String getURL() {        return URL;    }    public void setURL(String URL) {        this.URL = URL;    }    public String getUser() {        return user;    }    public void setUser(String user) {        this.user = user;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public int getMaxConnections() {        return maxConnections;    }    public void setMaxConnections(int maxConnections) {        this.maxConnections = maxConnections;    }    public String getValidationQuery() {        return validationQuery;    }    public void setValidationQuery(String validationQuery) {        this.validationQuery = validationQuery;    }    public boolean isValidateOnCheckout() {        return validateOnCheckout;    }    public void setValidateOnCheckout(boolean validateOnCheckout) {        this.validateOnCheckout = validateOnCheckout;    }    public int getIdleConnectionValidationSeconds() {        return idleConnectionValidationSeconds;    }    public void setIdleConnectionValidationSeconds(int idleConnectionValidationSeconds) {        this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;    }    public DruidDataSource getDatasource() {        return datasource;    }    public void setDatasource(DruidDataSource datasource) {        this.datasource = datasource;    }    public String getDiscardIdleConnectionsSeconds() {        return discardIdleConnectionsSeconds;    }    public void setDiscardIdleConnectionsSeconds(String discardIdleConnectionsSeconds) {        this.discardIdleConnectionsSeconds = discardIdleConnectionsSeconds;    }}

Quartz的配置文件

AppConfig用于获取自定义配置(下篇将会介绍自定义配置的实现方式)

package com.lingdu.welend.config.quartz;import com.lingdu.welend.config.web.AppConfig;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.io.IOException;import java.util.Properties;/** * @author Lee * @// TODO 2018/6/1-13:43 * @description */@Configurationpublic class QuartzConfiguration {    @Autowired    private AppConfig appConfig;    @Bean    public Scheduler scheduler() throws IOException, SchedulerException {        SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties());        Scheduler scheduler = schedulerFactory.getScheduler();        scheduler.start();        return scheduler;    }    @Bean    public Properties quartzProperties() throws IOException {        Properties prop = new Properties();        prop.put("quartz.scheduler.instanceName", appConfig.getQuartzSchedulerInstanceName());        prop.put("org.quartz.scheduler.instanceId", appConfig.getQuartzSchedulerInstanceId());        prop.put("org.quartz.scheduler.skipUpdateCheck", appConfig.getQuartzSchedulerSkipUpdateCheck());        prop.put("org.quartz.scheduler.jobFactory.class", appConfig.getQuartzSchedulerJobFactoryClass());        prop.put("org.quartz.jobStore.class", appConfig.getQuartzJobStoreClass());        prop.put("org.quartz.jobStore.driverDelegateClass", appConfig.getQuartzJobStoreDriverDelegateClass());        prop.put("org.quartz.jobStore.dataSource", appConfig.getQuartzJobStoreDatasource());        prop.put("org.quartz.jobStore.tablePrefix", appConfig.getQuartzJobStoreTablePrefix());        prop.put("org.quartz.jobStore.isClustered", appConfig.getQuartzJobStoreIsClustered());        prop.put("org.quartz.threadPool.class", appConfig.getQuartzThreadPoolClass());        prop.put("org.quartz.threadPool.threadCount", appConfig.getQuartzThreadPoolThreadCount());        prop.put("org.quartz.dataSource.quartzDataSource.connectionProvider.class", appConfig.getQuartzDatasourceQuartzDataSourceConnectionProviderClass());        prop.put("org.quartz.dataSource.quartzDataSource.driver", appConfig.getQuartzDatasourceQuartzDataSourceDriver());        prop.put("org.quartz.dataSource.quartzDataSource.URL", appConfig.getQuartzDatasourceQuartzDataSourceUrl());        prop.put("org.quartz.dataSource.quartzDataSource.user", appConfig.getQuartzDatasourceQuartzDataSourceUser());        prop.put("org.quartz.dataSource.quartzDataSource.password", appConfig.getQuartzDatasourceQuartzDataSourcePassword());        prop.put("org.quartz.dataSource.quartzDataSource.maxConnections", appConfig.getQuartzDatasourceQuartzDataSourceMaxConnections());        return prop;    }}

CURD——配置定时任务

接下来我们要实现怎么将定时任务配置在数据库中。首先 看实体类

/** * @author Lee * @// TODO 2018/6/1-13:27 * @description */public class TaskEntity implements Serializable {    private final Long serialVersion = -12654128415L;    private Long id; //ID    private String jobName; //任务名称    private String jobGroup; //任务分组    private String jobStatus; //任务状态    private String jobClass;//任务执行方法    private String cronExpression; // cron 表达式    private String jobDescription; //任务描述    private String timeZoneId; // 时区    private Long startTime;    private Long endTime;    private String state; //状态   public Long getId() {        return id;    }    public void setId(Long id) {        this.id= id;    }    public String getJobName() {        return jobName;    }    public void setJobName(String jobName) {        this.jobName = jobName;    }    public String getJobGroup() {        return jobGroup;    }    public void setJobGroup(String jobGroup) {        this.jobGroup = jobGroup;    }    public String getJobStatus() {        return jobStatus;    }    public void setJobStatus(String jobStatus) {        this.jobStatus = jobStatus;    }    public String getJobClass() {        return jobClass;    }    public void setJobClass(String jobClass) {        this.jobClass = jobClass;    }    public String getCronExpression() {        return cronExpression;    }    public void setCronExpression(String cronExpression) {        this.cronExpression = cronExpression;    }    public String getJobDescription() {        return jobDescription;    }    public void setJobDescription(String jobDescription) {        this.jobDescription = jobDescription;    }    public String getTimeZoneId() {        return timeZoneId;    }    public void setTimeZoneId(String timeZoneId) {        this.timeZoneId = timeZoneId;    }    public Long getStartTime() {        return startTime;    }    public void setStartTime(Long startTime) {        this.startTime = startTime;    }    public Long getEndTime() {        return endTime;    }    public void setEndTime(Long endTime) {        this.endTime = endTime;    }    public String getState() {        return state;    }    public void setState(String state) {        this.state = state;    }}

Service

贴下主要逻辑的处理,Controller 就不写了

import com.lingdu.welend.exception.WelendException;import com.lingdu.welend.models.basic.task.dao.TaskDao;import com.lingdu.welend.models.basic.task.entity.TaskEntity;import com.lingdu.welend.models.basic.task.service.ITaskService;import com.lingdu.welend.models.common.entity.StatusCode;import org.apache.commons.lang3.time.DateFormatUtils;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.Date;import java.util.HashSet;import java.util.List;/** * @author Lee * @// TODO 2018/6/1-13:26 * @description */@Servicepublic class TaskServiceImpl implements ITaskService {    @Autowired    private TaskDao taskDao;    @Autowired    private Scheduler scheduler;    /**     * @param info     * @return     * @// TODO: 2018/6/8 保存定时任务     */    @SuppressWarnings("unchecked")    public Boolean addTask(TaskEntity info) {        String jobName = info.getJobName(),                jobGroup = info.getJobGroup(),                cronExpression = info.getCronExpression(),                jobDescription = info.getJobDescription();        try {            if (checkExists(jobName, jobGroup)) {                throw new WelendException(String.format("Job已经存在, jobName:{%s},jobGroup:{%s}", jobName, jobGroup));            }            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);            JobKey jobKey = JobKey.jobKey(jobName, jobGroup);            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(jobDescription).withSchedule(scheduleBuilder).build();            Class
clazz = (Class
) Class.forName(info.getJobClass()); JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(jobDescription).build(); scheduler.scheduleJob(jobDetail, trigger); return true; } catch (SchedulerException | ClassNotFoundException e) { throw new WelendException("类名不存在或执行表达式错误"); } } /** * @param taskEntity * @return * @// TODO: 2018/6/8 开始定时任务 */ @Override @Transactional(rollbackFor = Exception.class) public Boolean resumeTask(TaskEntity taskEntity) { try { scheduler.resumeJob(JobKey.jobKey(taskEntity.getJobName(), taskEntity.getJobGroup())); return true; } catch (Exception e) { throw new WelendException(StatusCode.FAILED); } } /** * @return * @// TODO: 2018/6/5 查询job */ @Override @Transactional(readOnly = true) public List
findTaskList(TaskEntity taskEntity) { return taskDao.findTaskList(taskEntity); } /** * 修改定时任务 * * @param info */ public Boolean updateTask(TaskEntity info) { String jobName = info.getJobName(), jobGroup = info.getJobGroup(), cronExpression = info.getCronExpression(), jobDescription = info.getJobDescription(), createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"); try { if (!checkExists(jobName, jobGroup)) { throw new WelendException(String.format("Job不存在, jobName:{%s},jobGroup:{%s}", jobName, jobGroup)); } TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); JobKey jobKey = new JobKey(jobName, jobGroup); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing(); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build(); JobDetail jobDetail = scheduler.getJobDetail(jobKey); jobDetail.getJobBuilder().withDescription(jobDescription); HashSet
triggerSet = new HashSet<>(); triggerSet.add(cronTrigger); scheduler.scheduleJob(jobDetail, triggerSet, true); return true; } catch (SchedulerException e) { throw new WelendException("类名不存在或执行表达式错误"); } } /** * @param taskEntity * @// TODO: 2018/6/1 停止任务 */ @Override @Transactional(rollbackFor = Exception.class) public Boolean pauseTask(TaskEntity taskEntity) { TriggerKey triggerKey = TriggerKey.triggerKey(taskEntity.getJobName(), taskEntity.getJobGroup()); try { if (checkExists(taskEntity.getJobName(), taskEntity.getJobGroup())) { scheduler.pauseTrigger(triggerKey); //停止触发器 } return true; } catch (Exception e) { e.printStackTrace(); throw new WelendException(e.getMessage()); } } /** * @param taskEntity * @return * @// TODO: 2018/6/7 删除任务 */ public Boolean deleteTask(TaskEntity taskEntity) { TriggerKey triggerKey = TriggerKey.triggerKey(taskEntity.getJobName(), taskEntity.getJobGroup()); try { if (checkExists(taskEntity.getJobName(), taskEntity.getJobGroup())) { scheduler.pauseTrigger(triggerKey); //停止触发器 scheduler.unscheduleJob(triggerKey); //移除触发器 return true; } } catch (SchedulerException e) { e.printStackTrace(); throw new WelendException(e.getMessage()); } return false; } /** * 验证是否存在 * * @param jobName * @param jobGroup * @throws SchedulerException */ private boolean checkExists(String jobName, String jobGroup) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); return scheduler.checkExists(triggerKey); }}

Quartz所有的操作对应的SQL语句自己都封装好了,所以我们只需要调用它提供的方法就行。我只写了一段mybatis的代码,用来查询任务列表

定时任务代码

切记要实现Job接口,并重写execute方法

@Componentpublic class TestTask implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("这是一个测试任务的!!!!!!!!!!");    }}

至此,Quartz实现定时任务可配置已经差不多了。关于Quarzt表的创建,贴出以下建表语句

## In your Quartz properties file, you'll need to set# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate### By: Ron Cordell - roncordell#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.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;

需要注意的是:不同的Quartz版本建表语句可能会有出入,我现在使用的Quartz的version是2.3.0。

最后,以上示例代码可在我的中找到。 我的个人公众号:developlee的潇洒人生。 关注了也不一定更新,更新就不得了了。

qrcode_for_gh_2bd3f44efa21_258

转载地址:http://ofrgl.baihongyu.com/

你可能感兴趣的文章
企业级 SpringCloud 教程 (七)高可用的分布式配置中心(Spring Cloud Config)
查看>>
区块链最全书单|深聊了50个微信群,学习区块链必读这20本书
查看>>
20个热门在线少儿编程网站【2019】
查看>>
Netty 即时通信 后端 (五)
查看>>
没有内涵段子可以刷了,利用Python爬取段友之家贴吧图片和小视频(含源码)
查看>>
打造极致性能数据库中间件丨LVS+Keepalive+华为云DDM之理论篇
查看>>
分布式微服务云架构开发Web应用
查看>>
架构的代码结构
查看>>
MaxCompute推出面向开发者的专属版本,普惠大数据开发者
查看>>
MySQL 在高并发下的 订单撮合 系统使用 共享锁 与 排他锁 保证数据一致性
查看>>
JavaScript数据类型检测总结
查看>>
带你深入探解Java的分级引用模型
查看>>
@Autowired的使用:推荐对构造函数进行注释
查看>>
Navicat使用教程:获取MySQL中的行数(第1部分)
查看>>
IT兄弟连 Java Web教程 经典案例2
查看>>
Ember.js 入门指南——路由简介
查看>>
flex如何在浏览器运行,调试?
查看>>
解决错误:unable to find the ncurses libraries
查看>>
Hibernate之二级缓存
查看>>
解决JSP中使用request乱码问题
查看>>