当前位置: 首页 > news >正文

quartz 动态添加job_spring boot Quartz基于持久化存储的动态管理

精彩回顾

我们在spring boot quartz定时任务基本使用及介绍和spring boot quartz持久化存储分别对quartz基本信息及持久化存储进行了介绍。
这篇文章我们继续介绍给予持久化存储实现任务的动态管理。

创建表结构

为了存储我们自己动态创建的任务,除了spring boot quartz持久化存储
介绍的添加quartz表结构之外,我们还需要添加一个自己的表。以下是MySQL的表结构,其他类型的数据库请按需修改。

/* Navicat Premium Data Transfer Source Server         : localhost Source Server Type    : MySQL Source Server Version : 80021 Source Host           : localhost:3306 Source Schema         : quartz Target Server Type    : MySQL Target Server Version : 80021 File Encoding         : 65001 Date: 30/09/2020 13:34:24*/SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for task_quartz-- ----------------------------DROP TABLE IF EXISTS `task_quartz`;CREATE TABLE `task_quartz`  (  `id` bigint(0) NOT NULL AUTO_INCREMENT,  `job_group` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务分组',  `job_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务名',  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务描述',  `cron_expression` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'cron表达式',  `job_class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',  `job_status` varchar(5) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '任务状态',  `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '创建者',  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',  `modify_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '更新者',  `modify_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',  PRIMARY KEY (`id`) USING BTREE,  UNIQUE INDEX `NameWithGroup`(`job_group`, `job_name`) USING BTREE COMMENT '任务及分组唯一') ENGINE = MyISAM AUTO_INCREMENT = 68 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

创建工程,添加依赖

如果要实现任务的动态管理,这里单独借助一张表,存储任务的信息。
先介绍一个依赖的情况:

  1. MySQL数据库
  2. mybatis执行sql
  3. quartz依赖
  4. lombok
    具体项目依赖如下:
        org.springframework.boot            spring-boot-starter-quartz        org.mybatis.spring.boot            mybatis-spring-boot-starter            2.1.3mysql            mysql-connector-java            runtime

修改配置文件

application.yaml

server:  port: 8080spring:  profiles:    active: dev

application-dev.yaml

spring:  datasource:    url: jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&&serverTimezone=UTC    username: root    password: root    type: com.zaxxer.hikari.HikariDataSource  quartz:    job-store-type: jdbcmybatis:  mapper-locations: classpath:mapper/*.xml  type-aliases-package: net.xiangcaowuyu.quartztask.entity  configuration:    map-underscore-to-camel-case: true

主要配置信息:

  1. MySQL数据库连接
  2. mybatis配置
  3. job-store-type存储到数据库

增加mybatis相关操作

TaskQuartzMapper.xml

<?xml version="1.0" encoding="UTF-8"?>    id, job_group, job_name, description, cron_expression, job_class_name, job_status,     create_by, create_time, modify_by, modify_time          select                from task_quartz        where id = #{id,jdbcType=BIGINT}            select                from task_quartz        where job_name = #{jonName,jdbcType=VARCHAR} and job_group = #{jobGroup,jdbcType=VARCHAR}        delete from task_quartz    where id = #{id,jdbcType=BIGINT}          delete from task_quartz        where job_name = #{jonName,jdbcType=VARCHAR} and job_group = #{jobGroup,jdbcType=VARCHAR}        insert into task_quartz (job_group, job_name, description,       cron_expression, job_class_name, job_status,       create_by, create_time, modify_by,       modify_time)    values (#{jobGroup,jdbcType=VARCHAR}, #{jobName,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},       #{cronExpression,jdbcType=VARCHAR}, #{jobClassName,jdbcType=VARCHAR}, #{jobStatus,jdbcType=VARCHAR},       #{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{modifyBy,jdbcType=VARCHAR},       #{modifyTime,jdbcType=TIMESTAMP})          insert into task_quartz                        job_group,                            job_name,                            description,                            cron_expression,                            job_class_name,                            job_status,                            create_by,                            create_time,                            modify_by,                            modify_time,                            #{jobGroup,jdbcType=VARCHAR},                            #{jobName,jdbcType=VARCHAR},                            #{description,jdbcType=VARCHAR},                            #{cronExpression,jdbcType=VARCHAR},                            #{jobClassName,jdbcType=VARCHAR},                            #{jobStatus,jdbcType=VARCHAR},                            #{createBy,jdbcType=VARCHAR},                            #{createTime,jdbcType=TIMESTAMP},                            #{modifyBy,jdbcType=VARCHAR},                            #{modifyTime,jdbcType=TIMESTAMP},                    update task_quartz                        job_group = #{jobGroup,jdbcType=VARCHAR},                            job_name = #{jobName,jdbcType=VARCHAR},                            description = #{description,jdbcType=VARCHAR},                            cron_expression = #{cronExpression,jdbcType=VARCHAR},                            job_class_name = #{jobClassName,jdbcType=VARCHAR},                            job_status = #{jobStatus,jdbcType=VARCHAR},                            create_by = #{createBy,jdbcType=VARCHAR},                            create_time = #{createTime,jdbcType=TIMESTAMP},                            modify_by = #{modifyBy,jdbcType=VARCHAR},                            modify_time = #{modifyTime,jdbcType=TIMESTAMP},                    where id = #{id,jdbcType=BIGINT}        update task_quartz    set job_group = #{jobGroup,jdbcType=VARCHAR},      job_name = #{jobName,jdbcType=VARCHAR},      description = #{description,jdbcType=VARCHAR},      cron_expression = #{cronExpression,jdbcType=VARCHAR},      job_class_name = #{jobClassName,jdbcType=VARCHAR},      job_status = #{jobStatus,jdbcType=VARCHAR},      create_by = #{createBy,jdbcType=VARCHAR},      create_time = #{createTime,jdbcType=TIMESTAMP},      modify_by = #{modifyBy,jdbcType=VARCHAR},      modify_time = #{modifyTime,jdbcType=TIMESTAMP}    where id = #{id,jdbcType=BIGINT}  

TaskQuartz.java

/** * @author laughing * @date 2020/9/30 * @site https://www.lisen.org */@Datapublic class TaskQuartz implements Serializable {    private Long id;    /**     * 任务分组     */    private String jobGroup;    /**     * 任务名     */    private String jobName;    /**     * 任务描述     */    private String description;    /**     * cron表达式     */    private String cronExpression;    /**     * 任务执行时调用哪个类的方法 包名+类名     */    private String jobClassName;    /**     * 任务状态     */    private String jobStatus;    /**     * 创建者     */    private String createBy;    /**     * 创建时间     */    private Date createTime;    /**     * 更新者     */    private String modifyBy;    /**     * 更新时间     */    private Date modifyTime;    private static final long serialVersionUID = 1L;}

TaskQuartzService.java

/** * @author laughing * @date 2020/9/30 * @site https://www.lisen.org */public interface TaskQuartzService {    /**     * 根据主键删除     * @param id 主键     * @return 删除行数     */    int deleteByPrimaryKey(Long id);    /**     * 插入     * @param record 实体     * @return 成功返回1     */    int insert(TaskQuartz record);    /**     * 插入修改的值     * @param record 实体     * @return 成功返回1     */    int insertSelective(TaskQuartz record);    /**     * 根据主键获取     * @param id 主键     * @return 实体     */    TaskQuartz selectByPrimaryKey(Long id);    /**     * 更新     * @param record 实体     * @return 更新成功返回1     */    int updateByPrimaryKeySelective(TaskQuartz record);    /**     * 更新所有值     * @param record 实体     * @return 成功返回1     */    int updateByPrimaryKey(TaskQuartz record);    /**     * 根据名称及分组查找     * @param jobName 任务名称     * @param jobGroup 任务分组     * @return 任务     */    TaskQuartz selectByJobNameAndJobGroup(@Param("jonName") String jobName, @Param("jobGroup") String jobGroup);    /**     * 根据名称及分组查找     * @param jobName 任务名称     * @param jobGroup 任务分组     * @return 任务     */    int deleteByJobNameAndJobGroup(@Param("jonName") String jobName,@Param("jobGroup") String jobGroup);}

TaskQuartzServiceImpl.java

/** * @author laughing * @date 2020/9/30 * @site https://www.lisen.org */@Servicepublic class TaskQuartzServiceImpl implements TaskQuartzService {    @Resource    TaskQuartzMapper taskQuartzMapper;    /**     * 根据主键删除     *     * @param id 主键     * @return 删除行数     */    @Override    public int deleteByPrimaryKey(Long id) {        return taskQuartzMapper.deleteByPrimaryKey(id);    }    /**     * 插入     *     * @param record 实体     * @return 成功返回1     */    @Override    public int insert(TaskQuartz record) {        return taskQuartzMapper.insert(record);    }    /**     * 插入修改的值     *     * @param record 实体     * @return 成功返回1     */    @Override    public int insertSelective(TaskQuartz record) {        return taskQuartzMapper.insertSelective(record);    }    /**     * 根据主键获取     *     * @param id 主键     * @return 实体     */    @Override    public TaskQuartz selectByPrimaryKey(Long id) {        return taskQuartzMapper.selectByPrimaryKey(id);    }    /**     * 更新     *     * @param record 实体     * @return 更新成功返回1     */    @Override    public int updateByPrimaryKeySelective(TaskQuartz record) {        return taskQuartzMapper.updateByPrimaryKeySelective(record);    }    /**     * 更新所有值     *     * @param record 实体     * @return 成功返回1     */    @Override    public int updateByPrimaryKey(TaskQuartz record) {        return taskQuartzMapper.updateByPrimaryKey(record);    }    /**     * 根据名称及分组查找     *     * @param jobName  任务名称     * @param jobGroup 任务分组     * @return 任务     */    @Override    public TaskQuartz selectByJobNameAndJobGroup(String jobName, String jobGroup) {        return taskQuartzMapper.selectByJobNameAndJobGroup(jobName,jobGroup);    }    /**     * 根据名称及分组查找     *     * @param jobName  任务名称     * @param jobGroup 任务分组     * @return 任务     */    @Override    public int deleteByJobNameAndJobGroup(String jobName, String jobGroup) {        return taskQuartzMapper.deleteByJobNameAndJobGroup(jobName,jobGroup);    }}

增加测试任务

PrintJob.java

/** * @author laughing * @date 2020/9/30 * @site https://www.lisen.org */public class PrintJob implements Job {    private final Logger logger = LoggerFactory.getLogger(PrintJob.class);    /**     * 执行任务     *     * @param jobExecutionContext     * @throws JobExecutionException     */    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        try {            logger.info("Hello Job执行时间: " + new Date() + "  Blog:" + jobExecutionContext.getJobDetail().getJobDataMap().get("blog"));            Thread.sleep(1000 * 5);            System.out.println("================执行完成========================");        } catch (Exception e) {            e.printStackTrace();        }    }}

测试新增任务

新增任务时,我们并没有创建quartz相关表,只是存储到task_quartz表中,任务启动时,插入quartz表

 /**     * 新增或者保存任务     * 任务只是存储到task_quartz表中,任务启动时,插入quartz表     *     * @param taskQuartz 实体     * @return 结果     */    @RequestMapping("saveQuartz")    public Result save(@RequestBody TaskQuartz taskQuartz) {        TaskQuartz task = taskQuartzService.selectByJobNameAndJobGroup(taskQuartz.getJobName(), taskQuartz.getJobGroup());        if (task == null) {            task = new TaskQuartz();            BeanUtils.copyProperties(taskQuartz, task);            taskQuartzService.insertSelective(task);        } else {            taskQuartzService.updateByPrimaryKeySelective(taskQuartz);        }        return Result.ok();    }

测试启动任务

任务启动时,启动任务时,将任务信息持久化到quartz表中

/**     * 启用任务     * 启动任务时,将任务信息持久化到quartz表中     *     * @param taskQuartz 实体     * @return 结果     */    @RequestMapping("startJob")    public Result startJob(@RequestBody TaskQuartz taskQuartz) {        try {            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);//            存在先删除            if (scheduler.checkExists(jobKey)) {                scheduler.deleteJob(jobKey);            }            Class classz = Class.forName(taskQuartz.getJobClassName());            JobDetail jobDetail = JobBuilder.newJob()                    .withDescription(taskQuartz.getDescription())                    .withIdentity(jobKey)                    .usingJobData("blog", "https://www.xiangcaowuyu.net")                    .ofType(classz).build();            Trigger trigger = TriggerBuilder.newTrigger()                    .withIdentity("Trigger_" + taskQuartz.getJobName(), "TriggerGroup_" + taskQuartz.getJobGroup())                    .withSchedule(CronScheduleBuilder.cronSchedule(taskQuartz.getCronExpression()))                    .startNow()                    .build();            scheduler.scheduleJob(jobDetail, trigger);        } catch (Exception exception) {            return Result.error(exception.getMessage());        }        return Result.ok();    }

通过postman测试,我们可以观察控制台,任务时10s执行一次

e4d232553dc6dec0b80d3ac3917b6155.png

暂停任务

/**     * 暂停任务     *     * @param taskQuartz 实体     * @return 结果     */    @RequestMapping("shutdown")    public Result shutdown(@RequestBody TaskQuartz taskQuartz) {        try {            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);            scheduler.pauseJob(jobKey);            return Result.ok();        } catch (Exception ex) {            return Result.error(ex.getMessage());        }    }

恢复任务

 /**     * 恢复任务     *     * @param taskQuartz 实体     * @return 结果     */    @RequestMapping("resumeJob")    public Result resumeJob(@RequestBody TaskQuartz taskQuartz) {        try {            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);            scheduler.resumeJob(jobKey);            return Result.ok();        } catch (Exception ex) {            return Result.error(ex.getMessage());        }    }

删除任务

/**     * 删除任务     *     * @param taskQuartz 实体     * @return 结果     */    @RequestMapping("removeJob")    public Result removeJob(@RequestBody TaskQuartz taskQuartz) {        try {            JobKey jobKey = getJobKeyByTaskQuartz(taskQuartz);            scheduler.deleteJob(jobKey);            taskQuartzService.deleteByJobNameAndJobGroup(taskQuartz.getJobName(),taskQuartz.getJobGroup());            return Result.ok();        } catch (Exception ex) {            return Result.error(ex.getMessage());        }    }

代码已上传到码云

下载代码

git clone https://gitee.com/lisen0629/lisen_org.git

使用

进入克隆的位置,执行命令进入对应工程
cd quartztask

相关文章:

  • 学python还是php_米凯seo: 到底是学Python、PHP还是Ruby?
  • python命名空间更改_python命名空间
  • vb 查找word中的字符 单元格坐标_Word天,原来查找和替换功能这么强大
  • python网课答案董付国_Python 董付国
  • 苹果手机运行python_JavaScript_iPhone手机上搭建nodejs服务器步骤方法,一、为在ios上面运行,编译jxco - phpStudy...
  • vba 怎么选择网页中的下拉框_书法、国画中怎么选择用纸?
  • python编写手机自动化脚本_使用appium+python编写手机游戏功能自动化
  • pythonrandom函数用法_Python之np.random.permutation()函数的使用
  • python显示文字框_自定义悬停框Plotly:Python以适应文本
  • seay svn漏洞利用工具_roptool 一种帮助您编写二进制漏洞利用的工具
  • springcloud全家桶_Spring cloud 微服务组件 mica 2.0.5GA 发布,添加对sentinel、undertow指标收集。...
  • 查看约束信息_谢菲尔德资源与蚌埠中恒签订“转型”约束钛铁矿承购协议
  • recyclerview item 有选中字体颜色_PPT金属文字怎么插入?PPT模板金属字体制作,PPT金属字体怎么做?...
  • 3d旋转相册代码源码_Qt Data Visualization ,让数据3D可视化
  • asp 执行 exe_Asp.Net Core学习笔记:(五)构建和部署
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 4. 路由到控制器 - Laravel从零开始教程
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • download使用浅析
  • export和import的用法总结
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JS笔记四:作用域、变量(函数)提升
  • KMP算法及优化
  • Next.js之基础概念(二)
  • 搞机器学习要哪些技能
  • 观察者模式实现非直接耦合
  • 类orAPI - 收藏集 - 掘金
  • 免费小说阅读小程序
  • 排序算法学习笔记
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 微信小程序实战练习(仿五洲到家微信版)
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 正则表达式
  • RDS-Mysql 物理备份恢复到本地数据库上
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #if #elif #endif
  • #Linux(Source Insight安装及工程建立)
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (Oracle)SQL优化技巧(一):分页查询
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (三)uboot源码分析
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • .net 调用php,php 调用.net com组件 --
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • @Async注解的坑,小心
  • @ComponentScan比较
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...