Quartz持久化(springboot整合mybatis版本实现调度任务持久化)--提供源码下载

1、Quartz持久化功能概述

1、实现使用quartz提供的默认11张持久化表存储quartz相关信息。

2、实现定时任务的编辑、启动、关闭、删除。

3、实现自定义持久化表存储quartz定时任务信息。

4、本案例使用springboot整合mybatis框架和MySQL数据库实现持久化

5、提供源码下载

2、认识quartz持久化

可以将调度信息存储到数据库中,进行持久化,当程序中断,再次启动的时候。任然会保留中断之前的数据,继续执行。

1、Quartz中通过JobStore来存储任务和触发器信息,Quartz默认使用RAMJobstore将任务和触发器的信息存储在内存中,但是当服务器宕机内存中的信息会丢失。

2、Quartz中通过JDBCJobStore将任务和触发器等信息保存在数据库中,实现持久化。

3、JDBCJobStoreSupport中包含两个子类:

JobStoreTX:表示自己管理事务,存储在数据库中,当程序中断,调度信息不会丢失,

支持事务,支持集群,再次启动时,会恢复因程序关闭,重启而错过的任务。

JobStoreCMT:表示使用容器管理事务

3、Quartz+MySQL持久化默认依赖的表信息

针对不同的数据库,表就放在不同的sql文件中。

如果你使用的是mysql数据库表信息就在tables_mysql.sql文件中。

重点:这些表不会自动执行,需要拷贝出来手动创建在你的数据库中。

mysql表信息如下

QRTZ _JOB_DETAILS 存储每一个已配置的Job的详细信息

QRTZ _TRIGGERS      存储已配置的Trigger的信息

QRTZ_BLOB_TRIGGERS    Trigger作为Blob类型存储

QRTZ _SIMPLE_TRIGGERS   存储SimpleTrigger的信息,包括重复次数、间隔、以及已触的次数

QRTZ _CRON_TRIGGERS  存储CronTrigger,包括Cron表达式和时区信息

QRTZ _SIMPROP_TRIGGERS存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种触发器

QRTZ _CALENDARS  存储Quartz的Calendar信息

QRTZ _PAUSED_TRIGGER_GRPS      存储已暂停的Trigger组的信息

QRTZ _FIRED_TRIGGERS   存储与已触发的Trigger相关的状态信息,以及相关Job的执行信息

QRTZ _SCHEDULER_STATE    存储少量的有关Scheduler的状态信息,和别的Scheduler实例

QRTZ _LOCKS   存储程序的悲观锁的信息

创表信息如下:

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

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)
);

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)
);

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)
);

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(200) 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)
);

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)
);

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),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

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)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

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)
);

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)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;

4、在MySQL数据库中创建表

5、quartz默认配置文档

配置文件位置:

配置参考文档:

https://www.w3cschool.cn/quartz_doc/quartz_doc-i7oc2d9l.html

6、创建springboot工程配置quartz持久化

在正式开始之前我们需要明确一点,quartz自带的表数据的添加功能是quartz源码中自带的,我们只需要正确的配置数据源即可自动的添加数据。

6.1、创建工程引入相关包信息

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>quartzpersistencedemo3</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>quartzpersistencedemo3</name>
    <description>quartzpersistencedemo3</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <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.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

6.2、配置连接数据相关参数

最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。

最重要的配置就是连接数据库及job-store-type: jdbc,其他的配置如果不需要都可以不写。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/quartz?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
  quartz:
    # 任务存储类型
    job-store-type: jdbc
    # 关闭时等待任务完成
    wait-for-jobs-to-complete-on-shutdown: false
    # 是否覆盖已有的任务
    overwrite-existing-jobs: true
    # 是否自动启动计划程序
    auto-startup: true
    # 延迟启动
    startup-delay: 0s
    jdbc:
      # 数据库架构初始化模式(never:从不进行初始化;always:每次都清空数据库进行初始化;embedded:只初始化内存数据库(默认值))
      # 注意:第一次启动后,需要将always改为never,否则后续每次启动都会重新初始化quartz数据库
      initialize-schema: never
      # 用于初始化数据库架构的SQL文件的路径
      # schema: classpath:sql/tables_mysql_innodb.sql
    # 相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            # 调度器实例名称
            instanceName: QuartzScheduler
            # 分布式节点ID自动生成
            instanceId: AUTO
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            # 表前缀
            tablePrefix: QRTZ_
            # 是否开启集群
            isClustered: true
            # 数据源别名(自定义)
            dataSource: quartz
            # 分布式节点有效性检查时间间隔(毫秒)
            clusterCheckinInterval: 10000
            useProperties: false
          # 线程池配置
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

6.3、创建quartz配置类

在配置类中配置JobDetail和trigger监听器

这个配置类只是添加任务的快捷方式,这中方式在下面的添加任务中会被替代。

@Configuration
public class QuartzJobConfig {
    @Bean
    public JobDetail jobDetail(){
        JobDetail detail= JobBuilder.newJob(MyQuartzJob.class)
                .withIdentity("job33","group33")
                .storeDurably()//设置Job持久化
                //设置job数据
                .usingJobData("username","xiaochun2")
                .usingJobData("useraddr","安徽合肥2")
                .build();
        return detail;
    }

    //创建触发器,触发实例
    @Bean
    public Trigger trigger(){
        //每隔5秒执行一次
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        Trigger trigger= TriggerBuilder.newTrigger()
                .forJob(jobDetail())
                .withIdentity("trigger33","group33")
                .withSchedule(cronScheduleBuilder)
                .startNow()
                .build();
        return trigger;
    }
}

6.4、创建job,配置任务具体内容

@Slf4j
public class MyQuartzJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        //执行的具体内容
        log.info("=========quartzpersistencedemo3--quartz具体内容============");
        System.out.println(context.getJobInstance());
        System.out.println(context.getJobDetail().getJobDataMap().get("username"));
    }
}

6.5、启动任务并自动向数据库添加数据

从图中可以看出,任务已经顺利的启动

6.6、查看数据库数据情况

【qrtz_cron_triggers表数据】

【qrtz_job_details表数据】

【qrtz_triggers表数据】

【qrtz_scheduler_state表数据】

6.7、暂停任务

说明1通过scheduler.pauseJob暂停任务。

说明2scheduler.pauseJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。

说明3本案例中只涉及到任务本身的暂停,考虑到业务的并发和分布式的情况,在暂停前可以判断一下任务是否存在,如果还创建了自己的业务表,应该在任务暂停后修改自己的表状态。个人业务表的所有操作按照常规操作即可。

@Controller
public class QuartzController {
    @Resource
    Scheduler scheduler;
    //暂停任务
    @RequestMapping("/suspendJob")
    @ResponseBody
    public String suspendJob(){
        String jobName="job33";
        String jobGroup="group33";
        try{
            scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));
            return "暂停成功";
        }catch (Exception e){
            return "暂停失败";
        }
    }
}

6.8、重启任务

重点说明:这个时候重启项目,程序会自动的加载QuartzConfig并创建JobDetailTrigger并自动的向数据库添加数据。

核心添加的qrtz_cron_triggersqrtz_job_detailsqrtz_triggersqrtz_scheduler_state

说明1通过scheduler.resumeJob重启任务

说明2scheduler. resumeJob需要的两个参数是qrtz_job_details表中的JOB_NAME和JOB_GROUP字段的值。

@Controller
public class QuartzController {

    @Resource
    Scheduler scheduler;

    //重启任务
    @RequestMapping("/resumeJob")
    @ResponseBody
    public String resumeJob() {
        String jobName="job33";
        String jobGroup="group33";
        try {
            //恢复任务
            scheduler.resumeJob(JobKey.jobKey(jobName,jobGroup));
            return "重启成功";
        } catch (SchedulerException e) {
            return "重启失败";
        }
    }
}

6.9、删除任务

删除任务会清除数据库中的数据

@Controller
public class QuartzController {
    @Resource
    Scheduler scheduler;
    //删除任务
    @RequestMapping("/removeJob")
    @ResponseBody
    public String removeJob() throws SchedulerException {
        String jobName="job33";
        String jobGroup="group33";
        //先暂停任务
        scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));
        //获取任务触发器
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        try {
            //停止触发器
            scheduler.pauseTrigger(triggerKey);
            //移除触发器
            scheduler.unscheduleJob(triggerKey);
            //删除任务
            scheduler.deleteJob(JobKey.jobKey(jobName,jobGroup));
            return "删除任务成功";
        } catch (SchedulerException e) {
            return "删除任务失败";
        }
    }
}

6.10、立即启动任务

重点:只会启动一次

@Controller
public class QuartzController {

    @Resource
    Scheduler scheduler;

    //立即启动任务
    @RequestMapping("/triggerJob")
    @ResponseBody
    public String triggerJob() {
        String jobName="job33";
        String jobGroup="group33";
        try {
            scheduler.triggerJob(JobKey.jobKey(jobName,jobGroup));
            return "启动成功";
        } catch (SchedulerException e) {
            return "启动失败";
        }
    }
}

6.11、添加任务

【添加任务依赖对象】

对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客

6.11.1、添加任务依赖对象

对时区不了解,可以看这篇文章:Java中ZonedDateTime使用详解及时间转化(java中获取时区)_java zoneddatetime-CSDN博客

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class JobInfo {
    private String jobName;//job名称
    private String jobGroup;//job所属组
    private String triggerName;//触发器名称
    private String jobDescription;//job任务描述
    private Map<String,Object> userData;//job携带的用户参数
    private String cron;//触发器规则
    private String timeZoneId;//当前时区
}

6.11.2、实现任务添加代码

在项目中使用到了ObjectMapper对象,将map转化成json字符串,不了解可以看文章:

Springboot中解析JSON字符串(jackson库ObjectMapper解析JSON字符串)-CSDN博客

重点:小伙伴需要注意了,创建任务的时候MyQuartzJob任务本身这个是需要提前创建的。

//添加任务
@RequestMapping(value = "/addJob",method = RequestMethod.POST)
@ResponseBody
public String  addJob(@RequestBody JobInfo jobInfo) throws JsonProcessingException {
    System.out.println("======addJob==="+jobInfo.toString());
    //通过jobKey判断任务是否唯一
    // jobKey有jobName和jobGroup组成
    JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
    try {
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (Objects.nonNull(jobDetail)) {
            scheduler.deleteJob(jobKey);
        }
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
    //将map转化成json的工具
    ObjectMapper objectMapper=new ObjectMapper();

    //任务详情
    JobDetail jobDetail = JobBuilder.newJob(MyQuartzJob.class)
            //jobDetail描述
            .withDescription(jobInfo.getJobDescription())  //任务描述
            .usingJobData("userData",objectMapper.writeValueAsString(jobInfo.getUserData()))
            .withIdentity(jobKey) //指定任务
            .build();
    //根据cron,TimeZone时区,指定执行计划
    CronScheduleBuilder builder =
            CronScheduleBuilder
            //任务表达式
            .cronSchedule(jobInfo.getCron())
            .inTimeZone(TimeZone.getTimeZone(jobInfo.getTimeZoneId()));

    //触发器
    Trigger trigger = TriggerBuilder.newTrigger()
            .withIdentity(jobInfo.getTriggerName(), jobInfo.getJobGroup()).startNow()
            .withSchedule(builder)
            .build();

    //添加任务
    try {
        scheduler.scheduleJob(jobDetail, trigger);
        return "任务添加成功";
    } catch (SchedulerException e) {
        System.out.println(e.getMessage());
    }
    return "任务添加失败";
}

6.11.3、在postman中的测试

由于我们是在body中传递的数据,在addJob方法接受的参数需要使用@RequestBody注解,

如果不使用请求获取不到body的raw传递的数据。

测试参数:

{

  "jobName":"jobName1",

  "jobGroup":"jobGroup1",

  "triggerName":"triggerName1",

  "jobDescription":"三点、六点、九点发优惠卷。",

  "cron":"0/5 * * * * ?",

  "timeZoneId":"Asia/Shanghai",

  "userData":{"name":"123"}

}

数据库参数:

结果输出:

6.12、修改任务

修改任务的本质就是添加任务,只要保证jobName,jobGroup,triggerName等关键参数不变,即可修改数据。

7、自定义任务表

Quartz总共提供了11张表来持久化分布式任务调度的相关信息,总体来说功能强大,但是比较冗余。这个时候很多人希望自己创建一张简单的表,实现任务管理也是可以的。但是这个时候对自定义表的增删改查操作都需要自己写,而无法使用默认提供了功能。

创建信息可以参照如下:
CREATE TABLE `my_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `jobName` varchar(50) NOT NULL COMMENT '任务名称',
  `jobGroupName` varchar(50) NOT NULL COMMENT '任务组名',

  `jobTriggerName` varchar(50) NOT NULL COMMENT '触发器名称',
  `jobCron` varchar(50) NOT NULL COMMENT '时间规则表达式',
  `jobClassPath` varchar(200) NOT NULL COMMENT '类全类型',
  `jobDataMap` varchar(100) DEFAULT NULL COMMENT '用户数据',
  `jobStatus` int(2) NOT NULL COMMENT '任务状态',
  `jobDescribe` varchar(100) DEFAULT NULL COMMENT '任务功能描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

值得注意的是,如果这个时候通过自定义修改了任务状态为体质状态(如停止状态为1),修改之后还需要调用scheduler.pauseJob(JobKey.jobKey(jobName,jobGroup));,任他任务也是。因为我们的停止本质只是修改数据库的值。
 

8、源码下载

https://download.csdn.net/download/tangshiyilang/88660404

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tofu5m目标识别跟踪模块 跟踪模块

Tofu5m 是高性价比目标识别跟踪模块&#xff0c;支持可见光视频或红外网络视频的输入&#xff0c;支持视频下的多类型物体检测、识别、跟踪等功能。 产品支持视频编码、设备管理、目标检测、深度学习识别、跟踪等功能&#xff0c;提供多机版与触控版管理软件&#xff0c;为二次…

cuda加速求解龙格库塔四阶五步积分

一般代码使用cuda加速的方法&#xff1a; 使用PyTorch进行加速&#xff1a; 首先&#xff0c;你需要将你的ODE系统定义为PyTorch模型&#xff0c;这样可以利用PyTorch的自动微分功能和GPU加速。然后&#xff0c;你需要将数据和参数转换为PyTorch张量&#xff0c;并将它们移动到…

Java之AQS(AbstractQueuedSynchronizer)

Java之AQS&#xff08;AbstractQueuedSynchronizer&#xff09; AQS 介绍 AQS 的全称为 AbstractQueuedSynchronizer &#xff0c;翻译过来的意思就是抽象队列同步器。这个类在 java.util.concurrent.locks 包下面。 ● 是用来实现锁或者其他同步器组件的公共基础部分的抽象实…

抖店爆品之后,为什么流量一蹶不振?

我是电商珠珠 做抖店的商家&#xff0c;一般都会遇到在爆品之后&#xff0c;流量出现断崖式下跌的情况。很多商家并不知道是什么原因&#xff0c;觉得平台莫名其妙的。 我做抖店也已经有三年时间了&#xff0c;你们所遇到的问题都是我曾经遇到过的。 所以&#xff0c;出现这…

Mybatis缓存机制详解与实例分析

前言&#xff1a; 本篇文章主要讲解Mybatis缓存机制的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。 如果文章有什么需要改进的地方欢迎大佬提出&#xff0c;对大佬有帮助希望可以支持下哦~ 小威在此先感谢各位小伙伴儿了&#x1f601; 以下正文开始 Mybat…

2023_Spark_实验三十三:配置Standalone模式Spark3.4.2集群

实验目的&#xff1a;掌握Spark Standalone部署模式 实验方法&#xff1a;基于centos7部署Spark standalone模式集群 实验步骤&#xff1a; 一、下载spark软件 下载的时候下载与自己idea里对应版本的spark News | Apache Spark 选择任意一个下载即可 - spark 3.4.1 - spark …

PTA 最小生成树-kruskal

7-92 最小生成树-kruskal 分数 10 全屏浏览题目 作者 任唯 单位 河北农业大学 题目给出一个无向连通图&#xff0c;要求求出其最小生成树的权值。 温馨提示&#xff1a;本题请使用kruskal最小生成树算法。 输入格式: 输出格式: 输出一个整数表示最小生成树的各边的长度之和。…

通过字符设备驱动点亮板子上的led灯

通过字符设备驱动点亮板子上的led灯 app: test.c char buf[3] 1 0 0 0 1 0 0 0 1 ------------------|------------------------ kernel: led_driver.c -------------------|------------------------ hardware: RGB_led 应用程序如何将数据传递给驱动&#xff08;读写…

MySQL定时备份实现

一、备份数据库 –all-databases 备份所有数据库 /opt/mysqlcopy/all_$(date “%Y-%m-%d %H:%M:%S”).sql 备份地址 docker exec -it 容器名称 sh -c "mysqldump -u root -ppassword --all-databases > /opt/mysqlcopy/all_$(date "%Y-%m-%d %H:%M:%S").sq…

Docker 安装 MySQL5.7 和 MySQL8

文章目录 安装 MySQL5.7拉取镜像前期准备&#xff1a;启动容器 安装MySQL8.0拉取镜像查看镜像前期准备启动容器 安装 MySQL5.7 拉取镜像 docker pull mysql:5.7拉下来镜像后 执行 docker images 此时我们已经有这个镜像了。 前期准备&#xff1a; 在根目录下创建 app &…

Redis案例实战之Bitmap、Hyperloglog、GEO

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

Goland配置leetcode

1. 安装 首先在goland的setting界面上找到Plugins&#xff0c;然后搜索关键字leetcode&#xff0c;找到LeetCode Editor&#xff0c;安装它。 在安装后&#xff0c;第一次需要对其进行配置&#xff0c;在Tools中找到LeetCode Plugins&#xff0c;如下图所示进行配置。首先国内…

宝塔面板Linux服务器CentOS 7数据库mysql5.6升级至5.7版本教程

近段时间很多会员问系统更新较慢&#xff0c;也打算上几个好的系统&#xff0c;但几个系统系统只支持MYSQL5.7版本&#xff0c;服务器一直使用较低的MYSQL5.6版本&#xff0c;为了测试几个最新的系统打算让5.6和5.7并存使用&#xff0c;参考了多个文档感觉这种并存问题会很多。…

PHP+MySQL组合开发:万能在线预约小程序源码系统 附带完整的搭建教程

近年来&#xff0c;线上服务逐渐成为市场主流。特别是在预约服务领域&#xff0c;用户越来越倾向于选择方便快捷的线上预约方式。传统的预约方式如电话预约和到店预约不仅效率低下&#xff0c;而且在信息传达上存在很大的误差。这使得用户常常需要反复确认&#xff0c;浪费了大…

.NET 8最强新功能:键控服务依赖注入

什么是键控服务依赖注入&#xff1f; 在之前的依赖注入中&#xff0c;服务是根据其类型进行注册和解析的。如果出现同一接口有多个实现怎么办呢&#xff1f;这时候就可以使用.NET 8的新功能“键控服务依赖注入”。它允许您注册接口的多个实现&#xff0c;每个实现都与一个唯一…

10.Go 映射

映射&#xff08;map&#xff09;是一种特殊的数据结构&#xff0c;用于存储一系列无序的键值对&#xff0c;映射基于键来存储数据。映射功能强大的地方是&#xff0c;能够基于键快速检索数据。键就像索引一样&#xff0c;指向与该键关联的值。与C、Java中的映射的不同之处在于…

ECMAScript 的未来:预测 JavaScript 创新的下一个浪潮

以下是简单概括关于JavaScript知识点以及一些目前比较流行的比如&#xff1a;es6 想要系统学习&#xff1a; 大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&…

Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记

Cross-Drone Transformer Network for Robust Single Object Tracking论文阅读笔记 Abstract 无人机在各种应用中得到了广泛使用&#xff0c;例如航拍和军事安全&#xff0c;这得益于它们与固定摄像机相比的高机动性和广阔视野。多无人机追踪系统可以通过从不同视角收集互补的…

一站式指南:第 377 场力扣周赛的终极题解

比赛详情 比赛地址 题目一很简单题目二主要是题目长了点&#xff0c;其实解法很常规(比赛后才意识到)题目三套用Dijkstra算法题目四没时间解答水平还有待提升(其实就是需要灵活组合运用已知的算法&#xff0c;有点类似大模型的Agent) 题解和思路 第一题&#xff1a;最小数字…

AI时代下,如何看待“算法利维坦”?程序员客栈程序员客栈​

ChatGPT的浪潮从2022年袭来后&#xff0c;至今热度不减&#xff0c;呈现出蓬勃发展的趋势。AI家居、医疗、教育、金融、公益、农业、艺术......AI真的已经走进了生活的方方面面&#xff0c;我们仿佛已经进入了AI时代&#xff0c;势不可挡。人工智能水平如此之高&#xff0c;不禁…