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

news2025/2/7 11:44:02

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小白的实验室服务器深度学习环境配置指南

安装nvidia 本文在ubuntu server 22.04上实验成功&#xff0c;其他版本仅供参考 注意&#xff0c;本文仅适用于ubuntu server&#xff0c;不需要图形界面&#xff0c;没有对图形界面进行特殊考虑和验证&#xff01;依赖图形操作界面的读者慎用 查看是否安装了gcc gcc -v若没…

HTTP content-type内容类型的常见格式

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

因吹斯汀!只需上传照片,GPT-4V精准识别食物的卡路里和摄入热量

健身和减肥的朋友有福啦&#xff01; 最近一篇文章探索了GPT-4V在膳食评估领域的强大能力&#xff0c;可以根据饮食图片精准判断食物的种类与重量&#xff0c;并给出营养成分的分析&#xff0c;包括碳水化合物、蛋白质、脂肪占比。 最最重要的是&#xff0c;它还能告诉我们这…

Linux操作系统——进程(四)进程切换与命令行参数

进程切换 概念引入 下面我们先了解几个概念&#xff1a; 竞争性: 系统进程数目众多&#xff0c;而CPU资源只有少量&#xff0c;甚至1个&#xff0c;所以进程之间是具有竞争属性的。为了高效完成任务&#xff0c;更合理竞争相关资源&#xff0c;便具有了优先级 独立性: 多进程…

解决国内大模型痛点的最佳实践方案

1.前言 自AI热潮掀起以来&#xff0c;国内互联网大厂躬身入局&#xff0c;各类机构奋起追赶&#xff0c;创业型企业纷至沓来。业内戏称&#xff0c;一场大模型的“百模大战”已经扩展到“千模大战”。 根据近期中国科学技术信息研究所发布的《中国人工智能大模型地图研究报告…

关于linux mv指令机制

最近在mv文件的时候&#xff0c;操作失误将生产服务器一个1TB的文件夹mv到了/opt/test目录&#xff0c;因为最后/opt/目录被沾满所以1TB的文件夹没有迁移过来&#xff0c;写入了30GB数据到了/opt/test目录&#xff0c;因为系统分区被沾满&#xff0c;所以把test目录给删除了。 …

交换机端口镜像技术原理与配置

在网络维护的过程中会遇到需要对报文进行获取和分析的情况&#xff0c;比如怀疑有攻击报文&#xff0c;此时需要在不影响报文转发的情况下&#xff0c;对报文进行获取和分析。镜像技术可以在不影响报文正常处理流程的情况下&#xff0c;将镜像端口的报文复制一份到观察端口&…

OpenAI大模型DecryptPrompt

what is prompt 综述1.Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing(五星好评)综述2. Paradigm Shift in Natural Language Processing(四星推荐)综述3. Pre-Trained Models: Past, Present and Future Prompt即…

LeetCode刷题--- 优美的排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​​​​http://t.cs…

SQL手工注入漏洞测试(MySQL数据库)

一、实验平台 https://www.mozhe.cn/bug/detail/elRHc1BCd2VIckQxbjduMG9BVCtkZz09bW96aGUmozhe 二、实验目标 获取到网站的KEY&#xff0c;并提交完成靶场。 三、实验步骤 ①、启动靶机&#xff0c;进行访问查找可能存在注入的页面 ②、通过测试判断注入点的位置(id) (1)…

Unity VR Pico apk安装失败:INSTALL_FAILED_UPDATE_INCOMPATIBLE

我的报错&#xff1a; PICO4企业版。安装apk&#xff0c;报错“安装失败。&#xff08;所属的Unity项目打包的apk&#xff0c;被我在同一台pico4安装了20次&#xff09; 调试方法&#xff1a; PIco4发布使用UNITY开发的Vr应用&#xff0c;格式为apk&#xff0c;安装的时候发生…

Java多线程技术六——线程的状态(备份)

1 概述 线程在不同的运行时期存在不同的状态&#xff0c;状态信息在存在于State枚举类中&#xff0c;如下图。 每个状态的解释如下图 调用于线程有关的方法是造成线程状态改变的主要原因&#xff0c;因果关系如下图 从上图可知&#xff0c;在调用与线程有关的方法后&#xff0…

Scikit-Learn线性回归(一)

Scikit-Learn线性回归一 1、线性回归概述1.1、回归1.2、线性1.3、线性回归1.4、线性回归的优缺点1.5、线性回归与逻辑回归2、线性回归的原理2.1、线性回归的定义与原理2.2、线性回归的损失函数3、Scikit-Learn线性回归3.1、Scikit-Learn线性回归API3.2、Scikit-Learn线性回归初…

mac终端自定义登录欢迎语

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 shigen看着单调的终端&#xff0c;突然有了一丝丝的念头&#xff0c;我要搞的炫酷一点。让我想到的一个场景…

VMvare虚拟机之文件夹共享与防火墙设置

共享文件夹 什么是共享文件夹 共享文件夹是一种在网络上共享文件和文件夹的方法。它允许多个用户通过网络连接到共享文件夹&#xff0c;并可以访问其中的文件和文件夹&#xff0c;进行文件的读取、修改、删除等操作。共享文件夹可以用于方便地共享文件和协作工作&#xff0c;…

STL:std::array 和 基本数组类型array 浅谈一二三

一、优缺点比较 在C中&#xff0c;std::array是标准库提供的数组容器&#xff0c;相比于基础数据类型的数组&#xff0c;它具有以下优点和缺点&#xff1a; 优点&#xff1a; 安全性&#xff1a;std::array提供了边界检查&#xff0c;可以避免数组越界访问的问题。 可以作为…

在Centos7中利用Shell脚本:实现MySQL的数据备份

目录 自动化备份MySQL 一.备份数据库脚本 1.创建备份目录 2.创建脚本文件 3.新建配置文件&#xff08;连接数据库的配置文件&#xff09; 4.给文件权限(mysql_backup.sh) ​编辑 5.执行命令 (mysql_backup.sh) ​编辑 二.数据库通过备份恢复 1.创建脚…

jsonhandle 插件下载

网盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1hj4GKuGNyDNP2JzsJTLFtg 提取码&#xff1a;87rw 1.打开谷歌浏览器&#xff0c;选择扩展程序&#xff0c;记得选择为开发者模式&#xff0c;然后把下载好的CRX文件拖进去就行了

TCP通信流程

// TCP 和 UDP -> 传输层的协议 UDP : 用户数据报协议&#xff0c;面向无连接&#xff0c;可以单播&#xff0c;多播&#xff0c;广播&#xff0c; 面向数据报&#xff0c;不可靠&#xff08;接受方不会存储数据&#xff0c;也没有拥塞控制&#xff09;。效率高&#xff…

二维码智慧门牌管理系统升级:高效授权精准控制

文章目录 前言一、精确权限控制二、角色权限受限与透明操作三、提升工作效率与安全性 前言 二维码智慧门牌管理系统在企业管理中扮演着愈发重要的角色。通过系统升级&#xff0c;管理员可以配置权限角色&#xff0c;为单个或多个用户赋权&#xff0c;实现精准控制&#xff0c;…