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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 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
相关文章
|
3月前
|
Java Spring
Spring boot 运行服务jar外配置配置文件方式总结
Spring boot 运行服务jar外配置配置文件方式总结
488 0
|
13天前
|
缓存 前端开发 Java
springboot 的单体服务 字典参数转译
本文介绍了如何在Spring Boot项目中使用缓存来管理字典参数,并确保前后端数据一致性。首先,通过`@EnableCaching`启用缓存功能,接着创建一个自定义的字典缓存类`DicCache`。然后,通过配置类将`DicCache`添加到`cacheManager`中。此外,对字典服务进行改造,使用`@CachePut`和`@CacheEvict`注解保证数据一致性。最后,实现自定义注解`@DicSerializer`和序列化处理类`DictSerializerHandel`,用于在序列化过程中自动转换字典值。通过这种方式,可最小化代码改动并提高系统性能。
springboot 的单体服务 字典参数转译
|
2月前
|
小程序 JavaScript Java
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
|
2月前
|
Java Windows
SpringBoot Windows 自启动 - 通过 Windows Service 服务实现
SpringBoot Windows 自启动 - 通过 Windows Service 服务实现
48 2
|
2月前
|
Java 关系型数据库 MySQL
SpringBoot 集成 Quartz + MySQL
SpringBoot 集成 Quartz + MySQL
71 1
|
2月前
|
Java 开发者 Spring
"揭秘SpringBoot魔法SPI机制:一键解锁服务扩展新姿势,让你的应用灵活飞天!"
【8月更文挑战第11天】SPI(Service Provider Interface)是Java的服务提供发现机制,用于运行时动态查找和加载服务实现。SpringBoot在其基础上进行了封装和优化,通过`spring.factories`文件提供更集中的配置方式,便于框架扩展和组件替换。本文通过定义接口`HelloService`及其实现类`HelloServiceImpl`,并在`spring.factories`中配置,结合`SpringFactoriesLoader`加载服务,展示了SpringBoot SPI机制的工作流程和优势。
42 5
|
2月前
|
XML Java Maven
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
这篇文章详细介绍了如何在Spring Boot项目中使用logback进行日志记录,包括Maven依赖配置、logback配置文件的编写,以及实现的日志持久化和控制台输出效果。
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
|
2月前
|
NoSQL Java Linux
springboot+redis+虚拟机 springboot连接linux虚拟机中的redis服务
该博客文章介绍了如何在Spring Boot项目中通过配置和代码实现连接运行在Linux虚拟机上的Redis服务,并提供了详细的步骤和测试结果截图。
springboot+redis+虚拟机 springboot连接linux虚拟机中的redis服务
|
8天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
31 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
8天前
|
前端开发 JavaScript Java
SpringBoot项目部署打包好的React、Vue项目刷新报错404
本文讨论了在SpringBoot项目中部署React或Vue打包好的前端项目时,刷新页面导致404错误的问题,并提供了两种解决方案:一是在SpringBoot启动类中配置错误页面重定向到index.html,二是将前端路由改为hash模式以避免刷新问题。
49 1
下一篇
无影云桌面