SpringBoot3.x引入Quartz,持久化到MySQL数据库

示例版本

  • SpringBoot3.2.11
  • JDK17
  • MySQL5.7.38

Cron

在线Cron表达式生成器:https://www.pppet.net

持久化SQL语句

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;

项目改造

  1. 添加依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
  1. 配置yml文件
# 定时任务配置
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
          # 禁用调度器实例的恢复机制
          makeSchedulerThreadDaemon: true
        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
  1. 参数解释
    • 在Spring Boot中集成Quartz并使用数据库持久化时,spring.quartz.jdbc.initialize-schema 是一个重要配置项,它控制Quartz数据库表的初始化行为
      1. always:每次应用启动时都会尝试创建Quartz所需的数据库表(如果表不存在)。
      2. never:永远不会自动初始化表结构。可以执行Quartz发行包的docs/dbTables里的SQL文件来创建。
      3. embedded:仅当使用嵌入式数据库(如H2、HSQLDB、Derby)时才会初始化表结构。
    • spring.quartz.properties.org.quartz.threadPool.threadCount 是配置Quartz调度器线程池大小的关键参数,它决定了Quartz可以同时执行多少个作业。
      1. 如果使用JDBC JobStore,确保数据库连接池大小 ≥ Quartz线程数
      2. 不要设置过大,过大的线程数会导致:
        • 内存消耗增加
        • 线程上下文切换开销增大
        • 可能拖慢整个系统
      3. 典型配置范围:
        • 开发环境:5-10
        • 中小型生产环境:10-25
        • 大型高并发环境:25-50(不建议超过50)
  2. 创建测试执行方法

import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import java.util.Date;

/**
 * @Author WangHan
 * @Date 2025/7/31
 * @Description 继承 QuartzJobBean (更方便地使用 Spring 的依赖注入)
 */

@DisallowConcurrentExecution
@Slf4j
public class HelloJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        // 检查是否是恢复执行(应用重启后的执行)
        if (jobExecutionContext.isRecovering()) {
            log.info("Skipping HelloJob execution on recovery at: " + new Date());
            return; // 跳过恢复执行,不执行业务逻辑
        }

        log.info("execute HelloJob...." + new Date());
        // 你的实际业务逻辑放在这里
    }
}

  1. 创建service

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author WangHan
 * @Date 2025/7/31
 * @Description 定时任务服务
 */
@Service
public class QuartzJobService {

    @Autowired
    private Scheduler scheduler;

    /**
     * 新增定时任务
     *
     * @param jobName
     * @param jobGroup
     * @param triggerName
     * @param triggerGroup
     * @param jobClass
     * @param cron
     */
    public void addJob(String jobName, String jobGroup, String triggerName, String triggerGroup, String jobClass, String cron) throws Exception {
        Class<? extends Job> jobClazz = (Class<? extends Job>) Class.forName("com.platform.base.job." + jobClass);
        JobDetail jobDetail = JobBuilder.newJob(jobClazz)
                .withIdentity(jobName, jobGroup)
                .storeDurably()
                .build();

        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerName, triggerGroup)
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();

        scheduler.scheduleJob(jobDetail, cronTrigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    /**
     * 重启定时任务
     *
     * @param triggerName
     * @param triggerGroup
     * @param cron
     */
    public void rescheduleJob(String triggerName, String triggerGroup, String cron) throws Exception {
        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerKey)
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();
        scheduler.rescheduleJob(triggerKey, cronTrigger);
    }

    /**
     * 暂停定时任务
     *
     * @param jobName
     * @param jobGroup
     */
    public void pauseJob(String jobName, String jobGroup) throws Exception {
        scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
    }

    /**
     * 恢复定时任务
     *
     * @param jobName
     * @param jobGroup
     */
    public void resumeJob(String jobName, String jobGroup) throws Exception {
        scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
    }

    /**
     * 删除定时任务
     * @param jobName
     * @param jobGroup
     * @param triggerName
     * @param triggerGroup
     * @throws Exception
     */
    public void deleteJob(String jobName, String jobGroup, String triggerName, String triggerGroup) throws Exception {
        scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, triggerGroup));
        scheduler.unscheduleJob(TriggerKey.triggerKey(triggerName, triggerGroup));
        scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
    }

    /**
     * 查询所有定时任务
     *
     * @return
     */
    public List<String> listJobs() throws Exception {
        Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.anyGroup());
        return jobKeys.stream().map(JobKey::getName).collect(Collectors.toList());
    }

    /**
     * 立即执行指定的任务(不干扰原有的定时任务)
     *
     * @param jobName 任务名称
     * @param jobGroup 任务组
     */
    public void triggerJobOnce(String jobName, String jobGroup) throws Exception {
        JobKey jobKey = new JobKey(jobName, jobGroup);

        // 检查任务是否存在
        if (!scheduler.checkExists(jobKey)) {
            throw new IllegalArgumentException("任务不存在: " + jobName + "." + jobGroup);
        }

        // 立即触发执行指定的任务
        scheduler.triggerJob(jobKey);
    }
}

  1. 测试controller

import com.platform.base.service.quartz.QuartzJobService;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author WangHan
 * @Date 2025/7/31
 * @Description 定时任务
 */
@Tag(name = "定时任务管理接口", description = "定时任务管理接口")
@EnableTransactionManagement
@RestController
@RequestMapping("/v1/base/pc/quartz")
public class QuartzController {

    @Autowired
    private QuartzJobService quartzJobService;

    /**
     * 新增定时任务
     *
     * @param jobName      任务名称,示例:helloJob
     * @param jobGroup     任务组,示例:helloJobGroup
     * @param triggerName  触发器名称,示例:helloTrigger
     * @param triggerGroup 触发器组,示例:helloTriggerGroup
     * @param jobClass     调度任务,示例:HelloJob
     * @param cron         cron表达式,示例:0 0/1 * * * ?
     * @return String
     */
    @GetMapping(path = "/add")
    public String addJob(String jobName, String jobGroup, String triggerName, String triggerGroup, String jobClass, String cron) {
        try {
            quartzJobService.addJob(jobName, jobGroup, triggerName, triggerGroup, jobClass, cron);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 暂停任务
     *
     * @param jobName  任务名称
     * @param jobGroup 任务组
     * @return String
     */
    @GetMapping(path = "/pause")
    public String pauseJob(String jobName, String jobGroup) {
        try {
            quartzJobService.pauseJob(jobName, jobGroup);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 恢复任务
     *
     * @param jobName  任务名称
     * @param jobGroup 任务组
     * @return String
     */
    @GetMapping(path = "/resume")
    public String resumeJob(String jobName, String jobGroup) {
        try {
            quartzJobService.resumeJob(jobName, jobGroup);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 重启任务
     *
     * @param triggerName  触发器名称,示例:helloTrigger
     * @param triggerGroup 触发器组,示例:helloTriggerGroup
     * @param cron     cron表达式
     * @return String
     */
    @GetMapping(path = "/reSchedule")
    public String rescheduleJob(String triggerName, String triggerGroup, String cron) {
        try {
            quartzJobService.rescheduleJob(triggerName, triggerGroup, cron);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 删除任务
     *
     * @param jobName      任务名称,示例:helloJob
     * @param jobGroup     任务组,示例:helloJobGroup
     * @param triggerName  触发器名称,示例:helloTrigger
     * @param triggerGroup 触发器组,示例:helloTriggerGroup
     * @return String
     */
    @GetMapping(path = "/delete")
    public String deleteJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {
        try {
            quartzJobService.deleteJob(jobName, jobGroup, triggerName, triggerGroup);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 查询所有定时任务
     *
     * @return List<String>
     */
    @GetMapping(path = "/list")
    public List<String> listJobs() {
        try {
            return quartzJobService.listJobs();
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<String>();
        }
    }

    @GetMapping(path = "/runOnce")
    public String runOnce(String jobName, String jobGroup) {
        try {
            // 临时手动触发执行一次(不影响原有的定时任务)
            quartzJobService.triggerJobOnce(jobName, jobGroup);
            return "ok";
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }
}

  1. 接口调用
    • 查询列表
      在这里插入图片描述

    • 添加定时任务
      在这里插入图片描述

    • 删除定时任务
      在这里插入图片描述

    • 执行一次定时任务
      在这里插入图片描述

### 整合Spring Boot与Quartz实现数据库持久化的作业调度 #### 配置依赖项 为了使Spring Boot应用程序能够支持Quartz并利用`quartz-jobs`库来完成数据库中的作业存储,需先调整项目的构建文件。对于Maven项目,在`pom.xml`中加入如下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <!-- Quartz Jobs --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>${quartz.version}</version> </dependency> ``` 上述配置引入了必要的组件用于启动和管理定时任务以及通过JDBC连接到关系型数据库保存job详情[^1]。 #### 数据源设置 接着定义数据源属性以便于Quartz可以访问外部数据库执行持久操作。编辑`application.properties`或`application.yml`: ```yaml spring.datasource.url=jdbc:mysql://localhost:3306/quartz_db?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update ``` 这里指定了MySQL作为后台存储介质;当然也可以选择其他类型的RDBMS只要相应修改URL即可满足需求[^4]。 #### 初始化表结构 为了让Quartz能在指定的数据源上创建所需的表格,应该下载官方提供的SQL脚本并将之应用于目标schema内。通常这些DDL语句位于Quartz发行版下的`docs/dbTables`目录下找到适合版本的建表语句应用至实际环境中[^2]。 #### 自定义Job类 编写具体的业务逻辑单元即所谓的Jobs, 它们代表待被执行的任务体。下面给出一个简单的例子展示怎样继承自`Job`接口从而形成可被调度器识别的对象形式: ```java import org.quartz.Job; import org.quartz.JobExecutionContext; public class SampleJob implements Job { @Override public void execute(JobExecutionContext context){ System.out.println("Executing sample job at " + new Date()); } } ``` 此段代码实现了基本的日志记录功能每当触发条件达成时就会打印当前时间戳信息给控制台输出流[^3]。 #### 调度策略设定 最后一步就是安排何时何地运行已注册好的jobs了。这可以通过编程方式动态添加trigger实例或者静态声明的方式预先确定好计划参数。以下是采用Java Config风格的例子说明如何做到这一点: ```java @Configuration @EnableScheduling public class SchedulerConfig { @Autowired private ApplicationContext applicationContext; @Bean public JobDetailFactoryBean jobDetail(){ JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(SampleJob.class); factory.setDescription("Invoke SampleJob"); return factory; } @Bean public CronTriggerFactoryBean cronTrigger() throws ParseException{ CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); trigger.setCronExpression("*/5 * * * * ?"); //每五秒一次 trigger.setJobDetail(jobDetail().getObject()); return trigger; } } ``` 这段配置片段设置了每隔五分钟就激活一次之前提到过的SampleJob示例程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值