Springboot2.4.5集成Quartz实现动态任务数据持久化-不怕重启服务

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Springboot2.4.5集成Quartz实现动态任务数据持久化-不怕重启服务

基于数据库优点:服务器或者项目重启后,任务会自动重启接续(已错过时间的任务会立即执行)。

一、Quartz基础

建议通读一遍这个教程,熟悉Quartz基本概念。

https://www.w3cschool.cn/quartz_doc/

我们需要明白 Quartz 的几个核心概念,这样理解起 Quartz 的原理就会变得简单了。

  1. Job 表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:
void execute(JobExecutionContext context)
  1. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
  2. Trigger 代表一个调度参数的配置,什么时候去调。
  3. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

二、导入依赖(按需导入)

<!--    必须    定时任务-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--    根据自己数据导入    mysql依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.28</version>
     <scope>runtime</scope>
</dependency>
<!--        根据自己习惯导入 数据连接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<!--      根据自己需要导入  ORM框架-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>
<!--      根据自己需要导入   JSON-->
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.67</version>
 </dependency>
<!--      根据自己需要导入   swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
/dependency>

三、配置

配置文件

spring:
  #数据库配置信息
  datasource:
    url: jdbc:mysql://localhost:3306/xxxx?useUnicode=true&characterEncoding=utf-8
    username: xxxxxx
    type: com.alibaba.druid.pool.DruidDataSource
    password: xxxxxxx
  quartz:
    job-store-type: jdbc #数据库方式
    jdbc:
      initialize-schema: never #不初始化表结构
    properties:
      org:
        quartz:
          scheduler:
            instanceId: AUTO #默认主机名和时间戳生成实例ID,可以是任何字符串,但对于所有调度程序来说,必须是唯一的 对应qrtz_scheduler_state INSTANCE_NAME字段
            #instanceName: clusteredScheduler #quartzScheduler
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX #持久化配置
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #我们仅为数据库制作了特定于数据库的代理
            useProperties: false #以指示JDBCJobStore将JobDataMaps中的所有值都作为字符串,因此可以作为名称 - 值对存储而不是在BLOB列中以其序列化形式存储更多复杂的对象。从长远来看,这是更安全的,因为您避免了将非String类序列化为BLOB的类版本问题。
            tablePrefix: qrtz_  #数据库表前缀
            misfireThreshold: 60000 #在被认为“失火”之前,调度程序将“容忍”一个Triggers将其下一个启动时间通过的毫秒数。默认值(如果您在配置中未输入此属性)为60000(60秒)。
            clusterCheckinInterval: 5000 #设置此实例“检入”*与群集的其他实例的频率(以毫秒为单位)。影响检测失败实例的速度。
            isClustered: true #打开群集功能
          threadPool: #连接池
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

initialize-schema:

always:使用在这个选项,每次系统重启,软件会自动创建下边的数据表。

never:使用在这个选项,软件不会自动创建上边的数据表。

embedded:目前未知

我的处理方式配置为:always系统创建后,改为never;

手动建表SQL,initialize-schema: 先配置为always运行后会自动创建!!!

/*
 Navicat Premium Data Transfer
 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50733
 Source Host           : localhost:3306
 Source Schema         : fence
 Target Server Type    : MySQL
 Target Server Version : 50733
 File Encoding         : 65001
 Date: 26/04/2021 16:34:12
*/
 
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_blob_triggers`;
CREATE TABLE `qrtz_blob_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `BLOB_DATA` blob,
  PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  INDEX `SCHED_NAME`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_calendars
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_calendars`;
CREATE TABLE `qrtz_calendars`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `CALENDAR_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `CALENDAR` blob NOT NULL,
  PRIMARY KEY (`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_cron_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_cron_triggers`;
CREATE TABLE `qrtz_cron_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `CRON_EXPRESSION` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TIME_ZONE_ID` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_fired_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_fired_triggers`;
CREATE TABLE `qrtz_fired_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `ENTRY_ID` varchar(95) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `INSTANCE_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `FIRED_TIME` bigint(13) NOT NULL,
  `SCHED_TIME` bigint(13) NOT NULL,
  `PRIORITY` int(11) NOT NULL,
  `STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `JOB_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`SCHED_NAME`, `ENTRY_ID`) USING BTREE,
  INDEX `IDX_QRTZ_FT_TRIG_INST_NAME`(`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE,
  INDEX `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME`, `INSTANCE_NAME`, `REQUESTS_RECOVERY`) USING BTREE,
  INDEX `IDX_QRTZ_FT_J_G`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_FT_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_FT_T_G`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_FT_TG`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_job_details
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_job_details`;
CREATE TABLE `qrtz_job_details`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `JOB_CLASS_NAME` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `IS_DURABLE` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `IS_UPDATE_DATA` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_DATA` blob,
  PRIMARY KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_J_REQ_RECOVERY`(`SCHED_NAME`, `REQUESTS_RECOVERY`) USING BTREE,
  INDEX `IDX_QRTZ_J_GRP`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_locks
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_locks`;
CREATE TABLE `qrtz_locks`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `LOCK_NAME` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`SCHED_NAME`, `LOCK_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_paused_trigger_grps
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
CREATE TABLE `qrtz_paused_trigger_grps`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_scheduler_state
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_scheduler_state`;
CREATE TABLE `qrtz_scheduler_state`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `INSTANCE_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `LAST_CHECKIN_TIME` bigint(13) NOT NULL,
  `CHECKIN_INTERVAL` bigint(13) NOT NULL,
  PRIMARY KEY (`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_simple_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simple_triggers`;
CREATE TABLE `qrtz_simple_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci 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`) USING BTREE,
  CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_simprop_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
CREATE TABLE `qrtz_simprop_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `STR_PROP_1` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `STR_PROP_2` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `STR_PROP_3` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `INT_PROP_1` int(11) DEFAULT NULL,
  `INT_PROP_2` int(11) DEFAULT NULL,
  `LONG_PROP_1` bigint(20) DEFAULT NULL,
  `LONG_PROP_2` bigint(20) DEFAULT NULL,
  `DEC_PROP_1` decimal(13, 4) DEFAULT NULL,
  `DEC_PROP_2` decimal(13, 4) DEFAULT NULL,
  `BOOL_PROP_1` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `BOOL_PROP_2` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
-- ----------------------------
-- Table structure for qrtz_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_triggers`;
CREATE TABLE `qrtz_triggers`  (
  `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `JOB_GROUP` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `NEXT_FIRE_TIME` bigint(13) DEFAULT NULL,
  `PREV_FIRE_TIME` bigint(13) DEFAULT NULL,
  `PRIORITY` int(11) DEFAULT NULL,
  `TRIGGER_STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `TRIGGER_TYPE` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `START_TIME` bigint(13) NOT NULL,
  `END_TIME` bigint(13) DEFAULT NULL,
  `CALENDAR_NAME` varchar(190) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `MISFIRE_INSTR` smallint(2) DEFAULT NULL,
  `JOB_DATA` blob,
  PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_T_J`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_T_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_T_C`(`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE,
  INDEX `IDX_QRTZ_T_G`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE,
  INDEX `IDX_QRTZ_T_STATE`(`SCHED_NAME`, `TRIGGER_STATE`) USING BTREE,
  INDEX `IDX_QRTZ_T_N_STATE`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
  INDEX `IDX_QRTZ_T_N_G_STATE`(`SCHED_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
  INDEX `IDX_QRTZ_T_NEXT_FIRE_TIME`(`SCHED_NAME`, `NEXT_FIRE_TIME`) USING BTREE,
  INDEX `IDX_QRTZ_T_NFT_ST`(`SCHED_NAME`, `TRIGGER_STATE`, `NEXT_FIRE_TIME`) USING BTREE,
  INDEX `IDX_QRTZ_T_NFT_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`) USING BTREE,
  INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_STATE`) USING BTREE,
  INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
  CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
SET FOREIGN_KEY_CHECKS = 1;

四、核心service类、Job类

可以根据自己业务需求,修改Trigger的触发方式实现类Simple

Triggerhttps://www.w3cschool.cn/quartz_doc/quartz_doc-67a52d1f.html  CronTriggerhttps://www.w3cschool.cn/quartz_doc/quartz_doc-lwuv2d2a.html


Simple Trigger更适合传入一个具体时间执行,然后设置重复多少次;CronTrigger适合使用Cron表达式执行的重复任务;配合使用startTime和endTime可实现大多数业务。

package com.xxxx.service;
 
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;
 
import javax.annotation.PostConstruct;
import java.util.*;
 
import static org.quartz.TriggerBuilder.newTrigger;
 
 
@Service
public class QuartzService {
    @Autowired
    private Scheduler scheduler;
 
    @PostConstruct
    public void startScheduler() {
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 增加一个job
     *
     * @param jobClass
     *            任务实现类
     * @param jobName
     *            任务名称
     * @param jobGroupName
     *            任务组名
     * @param jobTime
     *            时间表达式
     * @param jobData
     *            参数
     */
    public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, Long jobTime, Map jobData) {
        try {
            // 任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .build();
            // 设置job参数
            if(jobData!= null && jobData.size()>0){
                jobDetail.getJobDataMap().putAll(jobData);
            }
            // 使用simpleTrigger规则
            Trigger trigger = null;
//            if (jobTimes < 0) {
//                trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
//                        .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
//                        .startNow().build();
//            } else {
                trigger =(SimpleTrigger)newTrigger()
                        .withIdentity(jobName, jobGroupName)
                        .startAt(new Date(jobTime)).build();
//            }
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 增加一个job
     *
     * @param jobClass
     *            任务实现类
     * @param jobName
     *            任务名称(建议唯一)
     * @param jobGroupName
     *            任务组名
     * @param jobTime
     *            时间表达式 (如:0/5 * * * * ? )
     * @param jobData
     *            参数
     */
    public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData) {
        try {
            // 创建jobDetail实例,绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定job类
            // 任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .build();
            // 设置job参数
            if(jobData!= null && jobData.size()>0){
                jobDetail.getJobDataMap().putAll(jobData);
            }
            // 定义调度触发规则
            // 使用cornTrigger规则
            // 触发器key
            Trigger trigger = newTrigger().withIdentity(jobName, jobGroupName)
                    .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();
            // 把作业和触发器注册到任务调度中
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 修改 一个job的 时间表达式
     *
     * @param jobName
     * @param jobGroupName
     * @param jobTime
     */
    public void updateJob(String jobName, String jobGroupName, String jobTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
            // 重启触发器
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /**
     * 修改 一个job的 未来时间
     *
     * @param jobName
     * @param jobGroupName
     * @param jobTime
     */
    public void updateJob(String jobName, String jobGroupName,Long jobTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
//            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
//                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
            SimpleTrigger trigger =(SimpleTrigger)newTrigger()
                    .withIdentity(jobName, jobGroupName)
                    .startAt(new Date(jobTime)).build();
            // 重启触发器
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 删除任务一个job
     *
     * @param jobName
     *            任务名称
     * @param jobGroupName
     *            任务组名
     */
    public void deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(new JobKey(jobName, jobGroupName));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 暂停一个job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void pauseJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 恢复一个job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void resumeJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 立即执行一个job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void runAJobNow(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取所有计划中的任务列表
     *
     * @return
     */
    public List<Map<String, Object>> queryAllJob() {
        List<Map<String, Object>> jobList = null;
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            jobList = new ArrayList<Map<String, Object>>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("jobName", jobKey.getName());
                    map.put("jobGroupName", jobKey.getGroup());
                    map.put("description", "触发器:" + trigger.getKey());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    map.put("jobStatus", triggerState.name());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        map.put("jobTime", cronExpression);
                    }
                    jobList.add(map);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }
 
    /**
     * 获取所有正在运行的job
     *
     * @return
     */
    public List<Map<String, Object>> queryRunJob() {
        List<Map<String, Object>> jobList = null;
        try {
            List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
            jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                Map<String, Object> map = new HashMap<String, Object>();
                JobDetail jobDetail = executingJob.getJobDetail();
                JobKey jobKey = jobDetail.getKey();
                Trigger trigger = executingJob.getTrigger();
                map.put("jobName", jobKey.getName());
                map.put("jobGroupName", jobKey.getGroup());
                map.put("description", "触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                map.put("jobStatus", triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    map.put("jobTime", cronExpression);
                }
                jobList.add(map);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }
}
package com.xxx.quartz.job;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSON;
import com.xxx.mapper.TaskMapper;
import com.xxx.model.Task;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
@Slf4j
public class Job extends QuartzJobBean {
    @Autowired
    TaskMapper taskMapper;
  
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 获取参数
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        Integer id=jobDataMap.getInt("id");
       //业务逻辑
       
    }
}

五、控制层业务;

建议:不建议研究quartz数据表及关系,建议自己再新建一个表,控制任务情况。大神忽略即可。

package com.xxxxx.controller;
 
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lets.common.AjaxJson;
import com.lets.mapper.TaskMapper;
import com.lets.model.Task;
import com.lets.quartz.job.Job;
import com.lets.service.DefenceService;
import com.lets.service.QuartzService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
 
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
 
@RestController
@RequestMapping("/admin/task")
@Api(tags = "定时任务")
public class AdminTaskController {
    @Autowired
    QuartzService quartzService;
   
    @Autowired
    TaskMapper taskMapper;
 
  
 
    @GetMapping("/add")
    @ApiOperation("添加一个任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "任务名称", defaultValue = "任务简单描述", required = true),
            @ApiImplicitParam(name = "type", value = "命令类型 xxxxxx", defaultValue = "", required = true),
            @ApiImplicitParam(name = "timeType", value = "时间类型1为具体时间 时间戳2为周期任务", defaultValue = "1", required = true),
            @ApiImplicitParam(name = "timeStr", value = "13位时间戳或cron表达式", required = true),
            @ApiImplicitParam(name = "parameter", value = "任务为7 8 9时须传递参数", required = false)
    })
    public AjaxJson add(@NotBlank @RequestParam String name, @NotBlank @RequestParam String type, @NotNull @RequestParam Integer timeType, @NotBlank @RequestParam String timeStr, String parameter) {
        Task task = new Task();
        String currentTimeMillis = System.currentTimeMillis() + "";
        task.setName(name);
        task.setJobName("name:" + currentTimeMillis);
        task.setJobGropName("Group:" + currentTimeMillis);
        task.setType(type);
        task.setTimeType(timeType);
        task.setTime(timeStr);
        if (parameter != null) {
            task.setParameter(parameter);
        }
        //传入参数校验
        boolean check = checkTask(task);
        if (check) {
            task.setTastState(1);
            taskMapper.insert(task);
            HashMap<String, Object> hm = new HashMap<>();
            hm.put("job_name", task.getJobName());
            hm.put("job_grop_name", task.getJobGropName());
            hm.put("id", task.getId());
            if (parameter != null) {
                hm.put("parameter", task.getParameter());
            }
            if (timeType == 1) {
                quartzService.addJob(Job.class, task.getJobName(), task.getJobGropName(), Long.valueOf(timeStr), hm);
            } else if (timeType == 2) {
                quartzService.addJob(Job.class, task.getJobName(), task.getJobGropName(), timeStr, hm);
            }
            return AjaxJson.ok("任务添加成功");
        } else {
            return AjaxJson.fail("传入参数非法");
        }
    }
 
    @GetMapping("/edit")
    @ApiOperation("更新一个任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "任务id", defaultValue = "1"),
            @ApiImplicitParam(name = "timeStr", value = "13位时间戳或cron表达式", required = true),
    })
    public AjaxJson edit(Integer id, @NotBlank @RequestParam String timeStr) {
        System.out.println(timeStr);
        Task task = taskMapper.selectById(id);
        task.setTime(timeStr);
        if (task.getTimeType() == 1) {
            quartzService.updateJob(task.getJobName(), task.getJobGropName(), Long.valueOf(timeStr));
        } else if (task.getTimeType() == 2) {
            quartzService.updateJob(task.getJobName(), task.getJobGropName(), timeStr);
        }
        taskMapper.updateById(task);
        return AjaxJson.ok("更新任务成功");
    }
 
    @GetMapping("/push")
    @ApiOperation("暂停一个任务")
    @ApiImplicitParam(name = "id", value = "任务id", defaultValue = "1")
    public AjaxJson push(Integer id) {
        Task task = taskMapper.selectById(id);
        System.out.println(JSON.toJSONString(task));
        quartzService.pauseJob(task.getJobName(), task.getJobGropName());
        task.setTastState(2);
        taskMapper.updateById(task);
        return AjaxJson.ok("暂停成功");
    }
    @GetMapping("/pushall")
    @ApiOperation("暂停所有任务")
    public AjaxJson pushall() {
        QueryWrapper<Task> taskQueryWrapper=new QueryWrapper<>();
        taskQueryWrapper.ne("tast_state",2);
        List<Task> tasks = taskMapper.selectList(taskQueryWrapper);
        if (tasks.isEmpty()) {
            return AjaxJson.ok("当前可暂停任务为空");
        }else {
            for (int i = 0; i < tasks.size(); i++) {
                quartzService.pauseJob(tasks.get(i).getJobName(), tasks.get(i).getJobGropName());
                tasks.get(i).setTastState(2);
                taskMapper.updateById(tasks.get(i));
            }
        }
        return AjaxJson.ok("暂停成功");
    }
 
    @GetMapping("/resume")
    @ApiOperation("恢复一个任务")
    @ApiImplicitParam(name = "id", value = "任务id", defaultValue = "1")
    public AjaxJson resumeJob(Integer id) {
        Task task = taskMapper.selectById(id);
        quartzService.resumeJob(task.getJobName(), task.getJobGropName());
        task.setTastState(1);
        taskMapper.updateById(task);
        return AjaxJson.ok("恢复成功");
    }
    @GetMapping("/resumeall")
    @ApiOperation("恢复全部任务")
    public AjaxJson resumeJob() {
        QueryWrapper<Task> taskQueryWrapper=new QueryWrapper<>();
        taskQueryWrapper.eq("tast_state",2);
        List<Task> tasks = taskMapper.selectList(taskQueryWrapper);
        if (tasks.isEmpty()) {
            return AjaxJson.ok("当前可恢复任务为空");
        }else {
            for (int i = 0; i < tasks.size(); i++) {
                quartzService.resumeJob(tasks.get(i).getJobName(), tasks.get(i).getJobGropName());
                tasks.get(i).setTastState(1);
                taskMapper.updateById(tasks.get(i));
            }
        }
        return AjaxJson.ok("恢复全部成功");
    }
 
    @GetMapping("/delete")
    @ApiOperation("删除一个任务")
    @ApiImplicitParam(name = "id", value = "任务id", defaultValue = "1")
    public AjaxJson deleteJob(Integer id) {
        Task task = taskMapper.selectById(id);
        quartzService.deleteJob(task.getJobName(), task.getJobGropName());
        taskMapper.deleteById(id);
        return AjaxJson.ok("删除成功");
    }
 
    @GetMapping("/deletebyname")
    @ApiOperation("删除一个任务(按照名称、分组)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jobName", value = "任务名称", defaultValue = "name:1619402010684"),
            @ApiImplicitParam(name = "jobGropName", value = "任务分组", defaultValue = "Group:1619402010684")
    })
    public AjaxJson deleteJobByName(String jobName, String jobGropName) {
        quartzService.deleteJob(jobName, jobGropName);
        return AjaxJson.ok("删除成功");
    }
 
    @GetMapping("/deleteall")
    @ApiOperation("删除全部任务")
    public AjaxJson deleteAll() {
        List<Task> tasks = taskMapper.selectList(null);
        if (!tasks.isEmpty()) {
            for (int i = 0; i < tasks.size(); i++) {
                quartzService.deleteJob(tasks.get(i).getJobName(), tasks.get(i).getJobGropName());
                taskMapper.deleteById(tasks.get(i).getId());
            }
            return AjaxJson.ok("删除全部成功");
        }
        return AjaxJson.ok("可删除任务为空");
    }
 
    @GetMapping("/findall")
    @ApiOperation("获取所有计划中的任务列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "currentpage", value = "页码", defaultValue = "1",required = true),
            @ApiImplicitParam(name = "pagesize", value = "每页条数", defaultValue = "10",required = true)
    })
    public AjaxJson findAllJob(@Min(value = 1) @RequestParam Integer currentpage, @Min(value = 1) @RequestParam(defaultValue = "10") Integer pagesize) {
 
        Page<Task> page = new Page<>(currentpage, pagesize);
        QueryWrapper<Task> taskQW = new QueryWrapper<>();
        taskQW.orderByDesc("id");
        Page<Task> pages = taskMapper.selectPage(page, taskQW);
        return AjaxJson.ok(pages);
    }
 
    //检查参数合法性
    private boolean checkTask(Task task) {
        //检查是否携带参数
        String type = task.getType();
        if(type.length()!=2){
            System.out.println("!=2");
            return false;
        }
        if (type.equals("07") || type.equals("08") || type.equals("09")) {
            if (task.getParameter() == null) {
                return false;
            }
        }
        Integer timeType = task.getTimeType();
        if (timeType == 1) {
            if (task.getTime().length() != 13) {
                return false;
            }
        }
        if (timeType == 2) {
            String[] s = task.getTime().split(" ");
            if (s.length != 6) {
                System.out.println("!=6");
                return false;
            }
        }
        if(timeType != 1 && timeType!= 2){;
            return false;
        }
        return true;
    }
}


封装的返回类

/**
 * Copyright &copy; 2005-2020 <a href="http://www.jhmis.com/">jhmis</a> All rights reserved.
 */
package com.xxxx.common;
 
import com.fasterxml.jackson.annotation.JsonIgnore;
 
import java.util.LinkedHashMap;
import java.util.List;
 
 
/**
 * $.ajax后需要接受的JSON
 *
 */
public class AjaxJson {
 
  private boolean success = true;// 是否成功
  private String errorCode = "-1";//错误代码
  private String msg = "操作成功";// 提示信息
    private Long count;             //返回表格记录数量
    private List<?> data;           //返回表格数据
  private LinkedHashMap<String, Object> body = new LinkedHashMap<String, Object>();//封装json的map
 
  public static AjaxJson ok(){
    AjaxJson j = new AjaxJson();
    return j;
  }
 
  public static AjaxJson ok(String msg){
    AjaxJson j = new AjaxJson();
    j.setMsg(msg);
    return j;
  }
 
  public static AjaxJson ok(String msg, Object object){
    AjaxJson j = new AjaxJson();
    j.setMsg(msg);
    j.setResult(object);
    return j;
  }
 
  public static AjaxJson ok(Object object){
    AjaxJson j = new AjaxJson();
    j.setResult(object);
    return j;
  }
 
  public static AjaxJson fail(String errorMsg){
    AjaxJson j = new AjaxJson();
    j.setSuccess(false);
    j.setErrorCode("999");//默认错误码
    j.setMsg(errorMsg);
    return j;
  }
 
  public static AjaxJson fail(String errorCode,String errorMsg){
    AjaxJson j = new AjaxJson();
    j.setSuccess(false);
    j.setErrorCode(errorCode);
    j.setMsg(errorMsg);
    return j;
  }
  //返回不分页的layui表数据
    public static AjaxJson layuiTable(List<?> list){
        AjaxJson j = new AjaxJson();
        j.setSuccess(true);
        j.setCount(Long.valueOf(list.size()));
        j.setData(list);
        return j;
    }
  public LinkedHashMap<String, Object> getBody() {
    return body;
  }
 
  public void setBody(LinkedHashMap<String, Object> body) {
    this.body = body;
  }
 
  public void put(String key, Object value){//向json中添加属性,在js中访问,请调用data.map.key
    body.put(key, value);
  }
  
  public void remove(String key){
    body.remove(key);
  }
 
  /**
   * 直接设置result内容
   * @param result
   */
  public void setResult(Object result){
    body.put("result", result);
  }
  @JsonIgnore//返回对象时忽略此属性
  public Object getResult(){
    return body.get("result");
  }
 
  public String getMsg() {
    return msg;
  }
 
  public void setMsg(String msg) {//向json中添加属性,在js中访问,请调用data.msg
    this.msg = msg;
  }
 
 
  public boolean isSuccess() {
    return success;
  }
 
  public void setSuccess(boolean success) {
    this.success = success;
  }
  
 
  public void setErrorCode(String errorCode) {
    this.errorCode = errorCode;
  }
 
  public String getErrorCode() {
    return errorCode;
  }
 
    public Long getCount() {
        return count;
    }
 
    public void setCount(Long count) {
        this.count = count;
    }
 
    public List<?> getData() {
        return data;
    }
 
    public void setData(List<?> data) {
        this.data = data;
    }
}

自定义的任务实体类

package com.xxxx.model;
 
import java.io.Serializable;
import java.util.Date;
 
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
 
/**
 * task
 * @author 
 */
@Data
public class Task implements Serializable {
    /**
     * 自增id
     */
    @TableId(type = IdType.AUTO)
    private Integer id;
 
    /**
     * 任务名称
     */
    private String name;
 
    /**
     * 任务创建人员
     */
    private String nickname;
 
    /**
     * 操作员id
     */
    private Integer userId;
 
    /**
     * 任务创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date createTime;
 
    /**
     * 时间类型1具体时间 2为cron表达式周期时间
     */
    private Integer timeType;
 
    /**
     * 任务执行时间
     */
    private String time;
 
    /**
     * jobGropName
     */
    private String jobGropName;
 
    /**
     * 参数
     */
    private String parameter;
 
    /**
     * jobName
     */
    private String jobName;
 
    /**
     * 备注
     */
    private String remark;
 
    /**
     * 命令类型
     */
    private String type;
 
    /**
     * 是否删除
     */
    @TableLogic
    private Byte isdelete;
 
    /**
     * 1开始 2为暂停 3已执行 
     */
    private Integer tastState;
 
    private static final long serialVersionUID = 1L;
}

实体类对应的sql

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ----------------------------
-- Table structure for task
-- ----------------------------
DROP TABLE IF EXISTS `task`;
CREATE TABLE `task`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务名称',
  `nickname` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务创建人员',
  `user_id` int(11) DEFAULT NULL COMMENT '操作员id',
  `create_time` datetime(0) DEFAULT NULL COMMENT '任务创建时间',
  `time_type` tinyint(2) DEFAULT NULL COMMENT '时间类型1具体时间 2为cron表达式周期时间',
  `time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '任务执行时间',
  `job_grop_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'jobGropName',
  `parameter` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '参数',
  `job_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'jobName',
  `remark` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
  `type` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '命令类型',
  `isdelete` tinyint(2) DEFAULT 0 COMMENT '是否删除\r\n是否删除',
  `tast_state` tinyint(2) DEFAULT NULL COMMENT '1开始 2为暂停 3已执行 ',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 
SET FOREIGN_KEY_CHECKS = 1;

数据库操作

package com.xxxx.mapper;
 
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lets.model.Task;
 
public interface TaskMapper extends BaseMapper<Task> {
}

六、写在最后

@Api。。。。。的注解都是Swagger的,有兴趣可以查看:https://blog.csdn.net/qq_29752857/article/details/113390619

欢迎大家一起讨论,如果能帮到你,我很开心。

吐槽一下百度,搜索技术类问题,前几页的答案几乎都是一样的,大家可以试试其他的搜搜。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
4天前
|
Java 关系型数据库 MySQL
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术的房屋租赁系统,旨在通过自动化和信息化手段提升房屋管理效率,优化租户体验。系统采用JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Layui和Spring Boot 2.0等技术栈,实现了高效的房源管理和便捷的租户服务。通过该系统,房东可以轻松管理房源,租户可以快速找到合适的住所,双方都能享受数字化带来的便利。未来,系统将持续优化升级,提供更多完善的服务。
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
|
1天前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
1天前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
|
1天前
|
XML JSON Java
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显
本文介绍了在Spring Boot中如何实现文件上传,包括单文件和多文件上传的实现,文件上传的表单页面创建,接收上传文件的Controller层代码编写,以及上传成功后如何在页面上遍历并显示上传的文件。同时,还涉及了`MultipartFile`类的使用和`@RequestPart`注解,以及在`application.properties`中配置文件上传的相关参数。
springboot文件上传,单文件上传和多文件上传,以及数据遍历和回显
|
2月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
186 6
|
2月前
|
Java 关系型数据库 MySQL
如何实现Springboot+camunda+mysql的集成
【7月更文挑战第2天】集成Spring Boot、Camunda和MySQL的简要步骤: 1. 初始化Spring Boot项目,添加Camunda和MySQL驱动依赖。 2. 配置`application.properties`,包括数据库URL、用户名和密码。 3. 设置Camunda引擎属性,指定数据源。 4. 引入流程定义文件(如`.bpmn`)。 5. 创建服务处理流程操作,创建控制器接收请求。 6. Camunda自动在数据库创建表结构。 7. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
208 4
|
2月前
|
消息中间件 Java 测试技术
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
163 1
|
3月前
|
消息中间件 Java Kafka
springboot集成kafka
springboot集成kafka
124 2
|
2月前
|
消息中间件 Java Kafka
Spring Boot与Apache Kafka Streams的集成
Spring Boot与Apache Kafka Streams的集成