全景网站开发待遇,工程网站模板,网站维护外包方案,上海十大好厂排名Quartz的分布式功能化设计 文章目录 Quartz的分布式功能化设计主体功能实现依赖API例子JOBJob记录表设计java具体代码DateDOOperatorDOSysQuartzJobDOPageDTOQuartzJobDTOQuartzJobPageDTOQuartzJobStatusEnumQuartzJobControllerIQuartzJobServiceQuartzJobServiceImplQuartzJ…Quartz的分布式功能化设计 文章目录 Quartz的分布式功能化设计主体功能实现依赖API例子JOBJob记录表设计java具体代码DateDOOperatorDOSysQuartzJobDOPageDTOQuartzJobDTOQuartzJobPageDTOQuartzJobStatusEnumQuartzJobControllerIQuartzJobServiceQuartzJobServiceImplQuartzJobMapperQuartzJobMapper.xmlSampleJob quartz分布式自带的管理表位置建表语句所在位置:
quartz-x.y.z.jar
org.quartz.imp.jdbcjobstore路径下这边只介绍Mysql的文件名为
table_mysql_innodb.sql。在sql文件中一共有11张表。 1.qrtz_blob_triggers
2.qrtz_cron_triggers
3.qrtz_simple_triggers
4.qrtz_simprop_triggers
5.qrtz_fired_triggers
6.qrtz_triggers
7.qrtz_job_details
8.qrtz_calendars
9.qrtz_paused_trigger_grps
10.qrtz_scheduler_state
11.qrtz_locks使用场景所有的任务都是针对业务来的并非公共调度平台所以侵入式代码库是可以的。
主体功能
通过新增数据库管理表(SYS_QUARTZ_JOB)来明确任务基本信息任务类型都是定时型支持新增任务只能存在一个在用的同名任务支持暂停任务支持恢复暂停的任务支持更新任务数据库管理表是更新操作而Quartz框架是进行了先删除在重建进行更新支持删除任务支持即时执行一次任务。
实现依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency!-- 打war包时加入此项 告诉spring-boot tomcat相关jar包用外部的不要打进去 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-tomcat/artifactIdscopeprovided/scope!-- 校验帮助包 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency!-- 任务调度quartz--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-quartz/artifactId/dependency!-- 数据源相关 分页插件page helper --dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactIdversion${pagehelper-spring-boot-starter.version}/version/dependencydependencygroupIdtk.mybatis/groupIdartifactIdmapper-spring-boot-starter/artifactIdversion${mapper-spring-boot-starter.version}/version/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis-spring-boot-starter.verson}/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql-connector-java.version}/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid-spring-boot-starter.version}/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdcom.alibaba.fastjson2/groupIdartifactIdfastjson2/artifactIdversion${fastjson2.version}/version/dependencydependencygroupIdcom.google.guava/groupIdartifactIdguava/artifactIdversion${gooogle-guava.version}/version/dependencyspringboot工程的集成quartz配置 application.properties
# quartz配置
spring.quartz.job-store-typejdbc
spring.quartz.jdbc.schemanever
spring.quartz.properties.org.quartz.scheduler.instanceNamequartzScheduler
spring.quartz.properties.org.quartz.scheduler.instanceIdAUTO
spring.quartz.properties.org.quartz.jobStore.dataSourcemysql
spring.quartz.properties.org.quartz.jobStore.classorg.springframework.scheduling.quartz.LocalDataSourceJobStore
spring.quartz.properties.driverDelegateClassorg.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefixQRTZ_
spring.quartz.properties.org.quartz.jobStore.isClusteredtrue
spring.quartz.properties.org.quartz.jobStore.misfireThreshold12000
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval15000
spring.quartz.properties.org.quartz.threadPool.classorg.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount1
spring.quartz.properties.org.quartz.threadPool.threadPriority5
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThreadtrueAPI
新建Quartz任务addJob(Validated RequestBody QuartzJobDTO quartzJobDTO,HttpServletRequest req)立即执行任务runJobNow(NotNull(message jobId不能为空) Long jobId, HttpServletRequest req)删除Quartz任务deleteJob(NotNull(message jobId不能为空) Long jobId, HttpServletRequest req)恢复Quartz任务针对暂停的任务resumeJob(NotBlank(message 任务完整类名不能为空) Size(max 250, message 最大长度250) String jobClassName, HttpServletRequest req)暂停Quartz任务pauseJob(NotBlank(message 任务完整类名不能为空) Size(max 250, message 最大长度250) String jobClassName, HttpServletRequest req)查询未删除的Quartz任务 分页式quartzJoblist(Validated RequestBody QuartzJobPageDTO quartzJobPageDto)更新Quartz任务采用先删除后增加的方式处理updateJob(Validated RequestBody UpdateQuartzJobDTO quartzJob, HttpServletRequest req)
例子JOB
SampleJob
新增JOB_API请求体
{jobClassName: com.donny.web.quartz.jobs.SampleJob,cronExpression: 0/20 * * * * ? ,description:测试简单Quartz任务20s执行一次,status: 1
}Job记录表设计
CREATE TABLE t_sys_quartz_job
(id BIGINT unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 主键,create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 修改时间,create_user VARCHAR(12) NOT NULL COMMENT 创建人,update_user VARCHAR(12) NOT NULL COMMENT 修改人,job_class_name VARCHAR(250) NOT NULL COMMENT 任务的类名,cron_expression VARCHAR(250) NULL COMMENT 任务的cron表达式,description VARCHAR(250) NULL COMMENT 任务的简要描述,status tinyint unsigned NOT NULL DEFAULT 0 COMMENT 任务的状态,0:正常,1:停止,is_deleted tinyint unsigned NOT NULL DEFAULT 0 COMMENT 任务是否已删除,0:否,1:是
) ENGINE InnoDB COMMENT quartz任务记录表;java具体代码
DateDO
package com.donny.web.model.entity;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;import javax.persistence.Column;
import java.io.Serializable;
import java.util.Date;/*** 数据库基础日期字段类主要针对数据库记录的两个日期字段** author donny* version 1.0* since 2024年01月17日 14:37*/
Data
public class DateDO implements Serializable {/*** 创建时间*/JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)Column(name create_time)private Date createTime;/*** 更新时间*/JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)Column(name update_time)private Date updateTime;
}OperatorDO
package com.donny.web.model.entity;import lombok.Data;
import lombok.EqualsAndHashCode;import javax.persistence.Column;
import java.io.Serializable;/*** 数据库基础字段操作者类主要针对更新记录操作人4个字段** author donny* version 1.0* since 2024年01月17日 14:38*/
Data
EqualsAndHashCode(callSuper true)
public class OperatorDO extends DateDO implements Serializable {/*** 创建者工号*/Column(name create_user)private String createUser;/*** 更新者工号*/Column(name update_user)private String updateUser;
}SysQuartzJobDO
package com.donny.web.model.entity;import lombok.Data;
import lombok.EqualsAndHashCode;import javax.persistence.*;
import java.io.Serializable;/*** sys_quartz_job的表映射Entity** author donny* version 1.0* since 2023/12/27*/
Data
EqualsAndHashCode(callSuper true)
Table(name t_sys_quartz_job)
public class SysQuartzJobDO extends OperatorDO implements Serializable {IdGeneratedValue(strategy GenerationType.IDENTITY)Column(name id)private Long id;/*** 任务类名*/Column(name job_class_name)private String jobClassName;/*** cron表达式*/Column(name cron_expression)private String cronExpression;/*** 描述*/Column(name description)private String description;/*** 状态 0正常 1停止*/Column(name status)private Integer status;/*** 逻辑删除标记*/Column(name is_deleted)private Integer isDeleted;}PageDTO
package com.donny.web.model.dto;import lombok.Getter;
import lombok.Setter;import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;/*** 分页查询的关于“页”的条件,供具体分页查询的业务DTO继承** author Donny* version 1.0* since 2023年12月27日 16:19*/
Setter
Getter
public class PageDTO {/*** 当前页码*/NotNull(message currentPage,当前页码不能为空)private Integer currentPage;/*** 每页记录数*/NotNull(message pageSize,每页记录数不能为空)Max(value 50, message 最大长度为50)private Integer pageSize;Overridepublic String toString() {return PageDTO{ currentPage currentPage , pageSize pageSize };}
}QuartzJobDTO
package com.donny.web.model.dto;import lombok.Getter;
import lombok.Setter;import javax.validation.constraints.*;/*** 供api使用* SysQuartzJob对象可供api设置的字段集合对象** author Donny* version 1.0* since 2023/12/27*/
Setter
Getter
public class QuartzJobDTO {/*** 创建者工号*/private String createUser;/*** 更新者工号*/private String updateUser;/*** 任务完整类名*/NotBlank(message jobClassName,不能为空)Size(max 250, message jobClassName最大长度250)private String jobClassName;/*** 调度周期 cron表达式*/NotBlank(message 调度周期cron表达式不能为空)Size(max 250, message cronExpression最大长度250)private String cronExpression;/*** 任务备注信息*/Size(max 250, message jobClassName最大长度250)private String description;/*** 状态 0正常 1停止*/NotNull(message status,状态不能为空)Max(value 1, message status不超过1)Min(value 0, message status不低于0)private Integer status;/*** 逻辑删除标记*/private Integer isDeleted;Overridepublic String toString() {return QuartzJobDTO{ , createUser createUser \ , updateUser updateUser \ , jobClassName jobClassName \ , cronExpression cronExpression \ , description description \ , status status , isDeleted isDeleted };}
}QuartzJobPageDTO
package com.donny.web.model.dto;import com.fasterxml.jackson.annotation.JsonFormat;import java.util.Date;/*** 供api使用* QuartzJob列表查询条件对象** author Donny* version 1.0* since 2023年12月28日 10:24*/
public class QuartzJobPageDTO extends PageDTO {/*** 任务类名*/private String jobClassName;/*** 状态 0正常 1停止*/private Integer status;/*** 创建时间*/JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)private Date startTime;/*** 修改时间*/JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)private Date endTime;public String getJobClassName() {return jobClassName;}public void setJobClassName(String jobClassName) {this.jobClassName jobClassName;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status status;}public Date getStartTime() {return null startTime ? null : (Date) startTime.clone();}public void setStartTime(Date startTime) {this.startTime null startTime ? null : (Date) startTime.clone();}public Date getEndTime() {return null endTime ? null : (Date) endTime.clone();}public void setEndTime(Date endTime) {this.endTime null endTime ? null : (Date) endTime.clone();}Overridepublic String toString() {return QuartzJobPageDTO{ jobClassName jobClassName \ , status status , startTime startTime , endTime endTime , currentPage super.getCurrentPage() , pageSize super.getPageSize() };}
}QuartzJobStatusEnum
package com.donny.web.quartz;/*** QuartzJob的Status 枚举值** author donny* version 1.0* since 2023年12月27日 16:30*/
public enum QuartzJobStatusEnum {NORMAL(0),STOPPED(1);private int status;QuartzJobStatusEnum(int status) {this.status status;}public int getValue() {return status;}public static String getDescription(QuartzJobStatusEnum status) {String description 待设状态;switch (status) {case NORMAL:description 正常;break;case STOPPED:description 已停止;break;default:break;}return description;}
}QuartzJobController
package com.donny.web.controller.manager;import com.donny.web.model.dto.QuartzJobPageDTO;
import com.donny.web.model.dto.UpdateQuartzJobDTO;
import com.donny.web.platform.pagehelper.PageBean;
import com.donny.web.model.dto.QuartzJobDTO;
import com.donny.web.model.entity.SysQuartzJobDO;
import com.donny.web.platform.ResponseBuilder;
import com.donny.web.platform.ReturnCode;
import com.donny.web.platform.WebReturnCode;
import com.donny.web.quartz.IQuartzJobService;
import com.donny.web.utils.PortalSessionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;/*** quartz的管理入口* 主体功能:p* 通过新增数据库管理表(SYS_QUARTZ_JOB)来明确任务基本信息p* 0.任务类型都是定时型p* 1.支持新增任务只能存在一个在用的同名任务p* 2.支持暂停任务p* 3.支持恢复暂停的任务p* 4.支持更新任务数据库管理表是更新操作而Quartz框架是进行了先删除在重建进行更新p* 5.支持删除任务p* 6.支持即时执行一次任务。** author Donny* version 1.0* since 2023/12/26*/
RestController
Validated
RequestMapping(value /api/v2/manager/quartz)
Slf4j
public class QuartzJobController {ResourceIQuartzJobService quartzJobService;/*** 新建Quartz任务** param quartzJobDTO {link QuartzJobDTO}*/PostMapping(value /addJob)public ResponseEntityReturnCode addJob(Validated RequestBody QuartzJobDTO quartzJobDTO,HttpServletRequest req) {String user PortalSessionUtils.getLoginUserId(req);quartzJobDTO.setCreateUser(user);quartzJobDTO.setUpdateUser(user);if (quartzJobService.addJob(quartzJobDTO)) {log.info(QuartzJob:[{}]已新增。, quartzJobDTO.getJobClassName());return ResponseBuilder.build(WebReturnCode.SUCCEED, 新增成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 新增失败, null);}}/*** 更新Quartz任务*/PostMapping(value /updateJob)public ResponseEntityReturnCode updateJob(Validated RequestBody UpdateQuartzJobDTO quartzJob,HttpServletRequest req) {quartzJob.setUpdateUser(PortalSessionUtils.getLoginUserId(req));if (quartzJobService.updateQuartzJob(quartzJob)) {log.info(QuartzJob:[{}]已更新。, quartzJob.getJobClassName());return ResponseBuilder.build(WebReturnCode.SUCCEED, 更新成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 更新失败, null);}}/*** 查询未删除的Quartz任务 分页式*/PostMapping(value /joblist)public ResponseEntityReturnCode quartzJoblist(Validated RequestBody QuartzJobPageDTO quartzJobPageDto) {PageBean pageBean new PageBean(quartzJobPageDto.getCurrentPage(), quartzJobPageDto.getPageSize());return ResponseBuilder.build(WebReturnCode.SUCCEED, quartzJobService.listAll(quartzJobPageDto, pageBean));}/*** 暂停Quartz任务** param jobClassName job的类名完成路径*/GetMapping(value /pauseJob)public ResponseEntityReturnCode pauseJob(NotBlank(message 任务完整类名不能为空)Size(max 250, message 最大长度250)String jobClassName,HttpServletRequest req) {SysQuartzJobDO job quartzJobService.findByJobClassName(jobClassName);if (null job) {return ResponseBuilder.build(WebReturnCode.FAILED, 暂停失败不存在该任务, null);}job.setUpdateUser(PortalSessionUtils.getLoginUserId(req));if (quartzJobService.pauseJob(job)) {log.info(QuartzJob:[{}]已暂停。, jobClassName);return ResponseBuilder.build(WebReturnCode.SUCCEED, 暂停成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 暂停失败, null);}}/*** 恢复Quartz任务** param jobClassName job的类名完整路径*/GetMapping(value /resumeJob)public ResponseEntityReturnCode resumeJob(NotBlank(message 任务完整类名不能为空)Size(max 250, message 最大长度250)String jobClassName,HttpServletRequest req) {SysQuartzJobDO job quartzJobService.findByJobClassName(jobClassName);if (null job) {return ResponseBuilder.build(WebReturnCode.FAILED, 恢复失败不存在该任务, null);}job.setUpdateUser(PortalSessionUtils.getLoginUserId(req));if (quartzJobService.resumeJob(job)) {log.info(QuartzJob:[{}]已恢复。, jobClassName);return ResponseBuilder.build(WebReturnCode.SUCCEED, 恢复成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 恢复失败, null);}}/*** 逻辑删除Quartz任务** param jobId Quartz任务的主键*/GetMapping(value /deleteJob)public ResponseEntityReturnCode deleteJob(NotNull(message jobId不能为空)Long jobId,HttpServletRequest req) {SysQuartzJobDO quartzJob quartzJobService.getJobById(jobId);if (quartzJob null) {return ResponseBuilder.build(WebReturnCode.SUCCEED, 不存在该任务, null);}quartzJob.setUpdateUser(PortalSessionUtils.getLoginUserId(req));if (quartzJobService.logicDeleteAndStopJob(quartzJob)) {log.info(QuartzJob:[{}]已删除。, quartzJob.getJobClassName());return ResponseBuilder.build(WebReturnCode.SUCCEED, 删除成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 删除失败, null);}}/*** 立即尝试执行一个任务** param jobId Quartz任务的主键*/GetMapping(value /runJobNow)public ResponseEntityReturnCode runJobNow(NotNull(message jobId不能为空)Long jobId,HttpServletRequest req) {SysQuartzJobDO quartzJob quartzJobService.getJobById(jobId);if (quartzJob null) {return ResponseBuilder.build(WebReturnCode.FAILED, 不存在该任务, null);}if (quartzJobService.runJobNow(quartzJob)) {log.info(QuartzJob:[{}]已执行。操作人[{}]。, quartzJob.getJobClassName(), PortalSessionUtils.getLoginUserId(req));return ResponseBuilder.build(WebReturnCode.SUCCEED, 执行成功, null);} else {return ResponseBuilder.build(WebReturnCode.FAILED, 执行失败, null);}}/*** 根据主键查询任务信息** param id {link UpdateQuartzJobDTO#getId()}*/GetMapping(value /get)public ResponseEntityReturnCode getQuartzJob(NotNull(message id不能为空)Long id) {try {return ResponseBuilder.build(WebReturnCode.SUCCEED, this.quartzJobService.getJobById(id));} catch (Exception e) {log.error(查询失败: e.getMessage(), e);return ResponseBuilder.build(WebReturnCode.FAILED, 查询失败: e.getMessage(), null);}}
}IQuartzJobService
package com.donny.web.quartz;import com.donny.web.model.dto.QuartzJobDTO;
import com.donny.web.model.dto.QuartzJobPageDTO;
import com.donny.web.model.entity.SysQuartzJobDO;
import com.donny.web.platform.pagehelper.PageBean;
import com.donny.web.platform.pagehelper.PageResult;/*** QuartzJob 服务层接口** author donny* version 1.0* since 2023/12/26*/
public interface IQuartzJobService {/*** 通过任务类名查询任务** param jobClassName 任务的*/SysQuartzJobDO findByJobClassName(String jobClassName);/*** 通过任务id查询任务** param id 任务的数据库主键*/SysQuartzJobDO getJobById(Long id);/*** 查询未删除的Quartz任务 分页式*/PageResultSysQuartzJobDO listAll(QuartzJobPageDTO quartzJobPageDto, PageBean pageBean);/*** 新增任务** param quartzJob {link QuartzJobDTO }*/boolean addJob(QuartzJobDTO quartzJob);/*** 更新任务** param quartzJob {link QuartzJobDTO }*/boolean updateQuartzJob(QuartzJobDTO quartzJob);/*** 逻辑删除任务** param quartzJob {link SysQuartzJobDO }*/boolean logicDeleteAndStopJob(SysQuartzJobDO quartzJob);/*** 暂停任务** param quartzJob {link SysQuartzJobDO }*/boolean pauseJob(SysQuartzJobDO quartzJob);/*** 恢复任务** param quartzJob {link SysQuartzJobDO }*/boolean resumeJob(SysQuartzJobDO quartzJob);/*** 立即执行任务** param quartzJob {link SysQuartzJobDO }*/boolean runJobNow(SysQuartzJobDO quartzJob);
}QuartzJobServiceImpl
package com.donny.web.quartz;import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.donny.web.dao.mysql.QuartzJobMapper;
import com.donny.web.model.dto.QuartzJobDTO;
import com.donny.web.model.dto.QuartzJobPageDTO;
import com.donny.web.model.dto.UpdateQuartzJobDTO;
import com.donny.web.model.entity.SysQuartzJobDO;
import com.donny.web.platform.exception.BusinessException;
import com.donny.web.platform.pagehelper.PageBean;
import com.donny.web.platform.pagehelper.PageResult;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** QuartzJob 服务层实现** author donny* version 1.0* since 2023/12/26*/
Service
public class QuartzJobServiceImpl implements IQuartzJobService {private static final Logger LOGGER LoggerFactory.getLogger(QuartzJobServiceImpl.class);Resourceprivate Scheduler scheduler;private final QuartzJobMapper quartzJobMapper;Autowiredpublic QuartzJobServiceImpl(QuartzJobMapper quartzJobMapper) {this.quartzJobMapper quartzJobMapper;}Overridepublic SysQuartzJobDO findByJobClassName(String jobClassName) {return this.quartzJobMapper.findByJobClassName(jobClassName);}Overridepublic SysQuartzJobDO getJobById(Long id) {return this.quartzJobMapper.getJobById(id);}Overridepublic PageResultSysQuartzJobDO listAll(QuartzJobPageDTO quartzJobPageDto, PageBean pageBean) {try (PageSysQuartzJobDO page PageMethod.startPage(pageBean.getCurrentPage(), pageBean.getPageSize())) {this.quartzJobMapper.listAll(quartzJobPageDto);return new PageResult(page.getResult(), page.getPageNum(), page.getPageSize(), page.getTotal());}}Overridepublic boolean addJob(QuartzJobDTO quartzJob) {SysQuartzJobDO result this.quartzJobMapper.findByJobClassName(quartzJob.getJobClassName().trim());if (null ! result) {return false;}schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim());int count this.quartzJobMapper.insert(quartzJob);return count 1;}/*** [Quartz框架] 添加定时任务*/private void schedulerAdd(String jobClassName, String cronExpression) {try {// 启动调度器this.scheduler.start();// 构建job信息JobDetail jobDetail JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).build();// 表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder CronScheduleBuilder.cronSchedule(cronExpression);// 按新的cronExpression表达式构建一个新的triggerCronTrigger trigger TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();this.scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {LOGGER.warn([Quartz Scheduler] 创建定时任务失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] 创建定时任务失败, e);}}private static Job getClass(String classname) {try {Class? class1 Class.forName(classname);return (Job) class1.newInstance();} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {LOGGER.warn([Quartz Scheduler] getClass获取对应类实例失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] getClass获取对应类实例失败);}}/*** [Quartz框架]删除定时任务*/private void schedulerDelete(String jobClassName) {try {/*使用给定的键暂停Trigger 。*/this.scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));/*从调度程序中删除指示的Trigger */this.scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));/*从 Scheduler 中删除已识别的Job - 以及任何关联的Trigger */this.scheduler.deleteJob(JobKey.jobKey(jobClassName));} catch (SchedulerException e) {LOGGER.warn([Quartz Scheduler] 删除定时任务失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] 删除定时任务失败);}}Overridepublic boolean updateQuartzJob(QuartzJobDTO quartzJob) throws BusinessException {try {schedulerDelete(quartzJob.getJobClassName().trim());schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim());if (QuartzJobStatusEnum.NORMAL.getValue() ! quartzJob.getStatus()) {this.scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));}} catch (SchedulerException e) {LOGGER.warn([Quartz Scheduler] 更新定时任务失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] 更新定时任务失败);}int count this.quartzJobMapper.update(quartzJob);return count 1;}Overridepublic boolean logicDeleteAndStopJob(SysQuartzJobDO quartzJob) {schedulerDelete(quartzJob.getJobClassName().trim());int count this.quartzJobMapper.logicDelete(quartzJob.getId(), quartzJob.getUpdateUser());return count 1;}Overridepublic boolean pauseJob(SysQuartzJobDO quartzJob) throws BusinessException {try {this.scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));} catch (SchedulerException e) {LOGGER.warn([Quartz Scheduler] 暂停定时任务失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] 暂停定时任务失败);}UpdateQuartzJobDTO quartzJobDto new UpdateQuartzJobDTO();quartzJobDto.setId(quartzJob.getId());quartzJobDto.setStatus(QuartzJobStatusEnum.STOPPED.getValue());int count this.quartzJobMapper.update(quartzJobDto);return count 1;}Overridepublic boolean resumeJob(SysQuartzJobDO quartzJob) throws BusinessException {try {this.scheduler.resumeJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));} catch (SchedulerException e) {LOGGER.warn([Quartz Scheduler] 恢复定时任务失败 e.getMessage(), e);throw new BusinessException([Quartz Scheduler] 恢复定时任务失败);}UpdateQuartzJobDTO quartzJobDto new UpdateQuartzJobDTO();quartzJobDto.setId(quartzJob.getId());quartzJobDto.setStatus(QuartzJobStatusEnum.NORMAL.getValue());quartzJobDto.setUpdateUser(quartzJob.getUpdateUser());int count this.quartzJobMapper.update(quartzJobDto);return count 1;}Overridepublic boolean runJobNow(SysQuartzJobDO quartzJob) {boolean flag true;try {JobKey jobKey JobKey.jobKey(quartzJob.getJobClassName().trim());this.scheduler.triggerJob(jobKey);} catch (SchedulerException e) {flag false;LOGGER.warn([Quartz Scheduler] 尝试执行任务失败 e.getMessage(), e);}return flag;}
}QuartzJobMapper
package com.donny.web.dao.mysql;import com.donny.web.model.dto.QuartzJobDTO;
import com.donny.web.model.dto.QuartzJobPageDTO;
import com.donny.web.model.entity.SysQuartzJobDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;import java.util.List;/*** author donny* version 1.0* since 2023/12/26*/
Repository
public interface QuartzJobMapper {int insert(Param(quartzJob) QuartzJobDTO quartzJob);int update(Param(quartzJob) QuartzJobDTO quartzJob);int logicDelete(Param(id) Long id, Param(updateUser) String updateUser);int physicalDelete(Param(id) Long id);/*** 根据job的ID主键查询未删除的任务** param id job的ID主键*/SysQuartzJobDO getJobById(Param(id) Long id);/*** 根据jobClassName查询存在的正常的未删除的job** param jobClassName job的类名完成路径*/SysQuartzJobDO findByJobClassName(Param(jobClassName) String jobClassName);/*** 查询未删除的** param quartzJobPageDto 查询条件对象*/ListSysQuartzJobDO listAll(Param(quartzJobPageDto) QuartzJobPageDTO quartzJobPageDto);
}QuartzJobMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.donny.web.dao.mysql.QuartzJobMapper!--定义查询数据库时表字段与java对象成员变量名的对应关系--resultMap typecom.donny.web.model.entity.SysQuartzJobDO idquartzJobMapid columnid propertyid/result columnjob_class_name propertyjobClassName/result columncron_expression propertycronExpression/result columndescription propertydescription/result columnstatus propertystatus/result columnis_deleted propertyisDeleted/result columncreate_time propertycreateTime/result columnupdate_time propertyupdateTime/result columncreate_user propertycreateUser/result columnupdate_user propertyupdateUser//resultMapinsert idinsert parameterTypecom.donny.web.model.dto.QuartzJobDTOinsert into t_sys_quartz_job(create_user, update_user, job_class_name, cron_expression, description)values (#{quartzJob.createUser},#{quartzJob.updateUser},#{quartzJob.jobClassName},#{quartzJob.cronExpression},#{quartzJob.description})/insertupdate idupdate parameterTypecom.donny.web.model.dto.QuartzJobDTOupdate t_sys_quartz_job sqjsetif testquartzJob.cronExpression ! null and quartzJob.cronExpression ! sqj.cron_expression #{quartzJob.cronExpression},/ifif testquartzJob.description ! null and quartzJob.description ! sqj.description #{quartzJob.description},/ifif testquartzJob.isDeleted ! null and quartzJob.isDeleted ! sqj.is_deleted #{quartzJob.isDeleted},/ifif testquartzJob.status ! nullsqj.status #{quartzJob.status},/ifif testquartzJob.updateUser ! null and quartzJob.updateUser ! sqj.update_user #{quartzJob.updateUser},/ifsqj.update_time NOW()/setwhere sqj.id #{quartzJob.id}/updateupdate idlogicDeleteupdate t_sys_quartz_job sqjsetsqj.update_time NOW(),sqj.update_user #{updateUser},sqj.is_deleted 1/setwhere sqj.id #{id}/updatedelete idphysicalDeletedeletefrom t_sys_quartz_jobwhere id #{id}/deleteselect idfindByJobClassName resultMapquartzJobMapselect sqj.id,create_time, update_time, create_user, update_user,job_class_name, cron_expression, description, status, is_deletedfrom t_sys_quartz_job sqjwheresqj.is_deleted 0if testjobClassName ! null and jobClassName ! and sqj.job_class_name#{jobClassName}/if/where/selectselect idlistAll parameterTypecom.donny.web.model.dto.QuartzJobPageDTO resultMapquartzJobMapselect sqj.id,create_time, update_time, create_user, update_user,job_class_name, cron_expression, description, status, is_deletedfrom t_sys_quartz_job sqjwheresqj.is_deleted0if testquartzJobPageDto.jobClassName ! null and quartzJobPageDto.jobClassName ! and sqj.job_class_name LIKE CONCAT(#{quartzJobPageDto.jobClassName}, %)/ifif testquartzJobPageDto.status ! nulland sqj.status #{quartzJobPageDto.status}/ifif testquartzJobPageDto.startTime ! null![CDATA[ and sqj.create_time #{quartzJobPageDto.startTime} ]]/ifif testquartzJobPageDto.endTime ! null![CDATA[ and sqj.create_time #{quartzJobPageDto.endTime} ]]/if/whereorder by sqj.id desc/selectselect idgetJobById resultMapquartzJobMapselect sqj.id,create_time,update_time,create_user,update_user,job_class_name,cron_expression,description,status,is_deletedfrom t_sys_quartz_job sqjwhere sqj.id #{id}and sqj.is_deleted 0/select/mapperSampleJob
package com.donny.web.quartz.jobs;import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;/*** author donny* version 1.0* since 2023年12月27日 15:58*/
Slf4j
public class SampleJob implements Job {Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {log.info(SampleJob is execute);}
}