spring-boot集成Quartz-job存储方式一JDBC
1、项目jar包依赖引入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
2、数据库建job运行表,可以详见quartz官方建表脚本
注意,在postgresql下有部分类型转换问题,mysql完美兼容
3、yml配置文件的配置
## quartz定时任务,采用数据库方式,driverDelegateClass是为兼容pgl数据库增加的 quartz: job-store-type: jdbc properties: org: quartz: jobStore: driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
4、实体类SysQuartzJob
package org.jeecg.modules.quartz.entity; import java.io.Serializable; import org.jeecgframework.poi.excel.annotation.Excel; import org.springframework.format.annotation.DateTimeFormat; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; /** * @Description: 定时任务在线管理 * @Author: jeecg-boot * @Date: 2019-01-02 * @Version: V1.0 */ @Data @TableName("sys_quartz_job") public class SysQuartzJob implements Serializable { private static final long serialVersionUID = 1L; /**id*/ @TableId(type = IdType.ID_WORKER_STR) private java.lang.String id; /**创建人*/ private java.lang.String createBy; /**创建时间*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private java.util.Date createTime; /**删除状态*/ private java.lang.Integer delFlag; /**修改人*/ private java.lang.String updateBy; /**修改时间*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private java.util.Date updateTime; /**任务类名*/ @Excel(name="任务类名",width=40) private java.lang.String jobClassName; /**cron表达式*/ @Excel(name="cron表达式",width=30) private java.lang.String cronExpression; /**参数*/ @Excel(name="参数",width=15) private java.lang.String parameter; /**描述*/ @Excel(name="描述",width=40) private java.lang.String description; /**状态 0正常 -1停止*/ @Excel(name="状态",width=15) private java.lang.Integer status; }
5、实现类SysQuartzJobServiceImpl
package org.jeecg.modules.quartz.service.impl; import java.util.List; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.modules.quartz.entity.SysQuartzJob; import org.jeecg.modules.quartz.mapper.SysQuartzJobMapper; import org.jeecg.modules.quartz.service.ISysQuartzJobService; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.TriggerBuilder; import org.quartz.TriggerKey; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; /** * @Description: 定时任务在线管理 * @Author: jeecg-boot * @Date: 2019-04-28 * @Version: V1.1 */ @Slf4j @Service public class SysQuartzJobServiceImpl extends ServiceImpl<SysQuartzJobMapper, SysQuartzJob> implements ISysQuartzJobService { @Autowired private SysQuartzJobMapper sysQuartzJobMapper; @Autowired private Scheduler scheduler; @Override public List<SysQuartzJob> findByJobClassName(String jobClassName) { return sysQuartzJobMapper.findByJobClassName(jobClassName); } /** * 保存&启动定时任务 */ @Override public boolean saveAndScheduleJob(SysQuartzJob sysQuartzJob) { if (CommonConstant.STATUS_NORMAL.equals(sysQuartzJob.getStatus())) { // 定时器添加 this.schedulerAdd(sysQuartzJob.getJobClassName().trim(), sysQuartzJob.getCronExpression().trim(), sysQuartzJob.getParameter()); } // DB设置修改 sysQuartzJob.setDelFlag(CommonConstant.DEL_FLAG_0); return this.save(sysQuartzJob); } /** * 恢复定时任务 */ @Override public boolean resumeJob(SysQuartzJob sysQuartzJob) { schedulerDelete(sysQuartzJob.getJobClassName().trim()); schedulerAdd(sysQuartzJob.getJobClassName().trim(), sysQuartzJob.getCronExpression().trim(), sysQuartzJob.getParameter()); sysQuartzJob.setStatus(CommonConstant.STATUS_NORMAL); return this.updateById(sysQuartzJob); } /** * 编辑&启停定时任务 * @throws SchedulerException */ @Override public boolean editAndScheduleJob(SysQuartzJob sysQuartzJob) throws SchedulerException { if (CommonConstant.STATUS_NORMAL.equals(sysQuartzJob.getStatus())) { schedulerDelete(sysQuartzJob.getJobClassName().trim()); schedulerAdd(sysQuartzJob.getJobClassName().trim(), sysQuartzJob.getCronExpression().trim(), sysQuartzJob.getParameter()); }else{ scheduler.pauseJob(JobKey.jobKey(sysQuartzJob.getJobClassName().trim())); } return this.updateById(sysQuartzJob); } /** * 删除&停止删除定时任务 */ @Override public boolean deleteAndStopJob(SysQuartzJob job) { schedulerDelete(job.getJobClassName().trim()); boolean ok = this.removeById(job.getId()); return ok; } /** * 添加定时任务 * * @param jobClassName * @param cronExpression * @param parameter */ private void schedulerAdd(String jobClassName, String cronExpression, String parameter) { try { // 启动调度器 scheduler.start(); // 构建job信息 JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build(); // 表达式调度构建器(即任务执行的时间) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); // 按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { throw new JeecgBootException("创建定时任务失败", e); } catch (RuntimeException e) { throw new JeecgBootException(e.getMessage(), e); }catch (Exception e) { throw new JeecgBootException("后台找不到该类名:" + jobClassName, e); } } /** * 删除定时任务 * * @param jobClassName */ private void schedulerDelete(String jobClassName) { try { scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName)); scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName)); scheduler.deleteJob(JobKey.jobKey(jobClassName)); } catch (Exception e) { log.error(e.getMessage(), e); throw new JeecgBootException("删除定时任务失败"); } } private static Job getClass(String classname) throws Exception { Class<?> class1 = Class.forName(classname); return (Job) class1.newInstance(); } }
6、接口类SysQuartzJobController
package org.jeecg.modules.quartz.controller; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.modules.quartz.entity.SysQuartzJob; import org.jeecg.modules.quartz.service.ISysQuartzJobService; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; /** * @Description: 定时任务在线管理 * @Author: jeecg-boot * @Date: 2019-01-02 * @Version:V1.0 */ @RestController @RequestMapping("/quartz/sysQuartzJob") @Slf4j public class SysQuartzJobController { @Autowired private ISysQuartzJobService quartzJobService; @Autowired private Scheduler scheduler; /** * 分页列表查询 * * @param sysQuartzJob * @param pageNo * @param pageSize * @param req * @return */ @RequestMapping(value = "/list", method = RequestMethod.GET) public Result<?> queryPageList(SysQuartzJob sysQuartzJob, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { QueryWrapper<SysQuartzJob> queryWrapper = QueryGenerator.initQueryWrapper(sysQuartzJob, req.getParameterMap()); Page<SysQuartzJob> page = new Page<SysQuartzJob>(pageNo, pageSize); IPage<SysQuartzJob> pageList = quartzJobService.page(page, queryWrapper); return Result.ok(pageList); } /** * 添加定时任务 * * @param sysQuartzJob * @return */ @RequestMapping(value = "/add", method = RequestMethod.POST) public Result<?> add(@RequestBody SysQuartzJob sysQuartzJob) { List<SysQuartzJob> list = quartzJobService.findByJobClassName(sysQuartzJob.getJobClassName()); if (list != null && list.size() > 0) { return Result.error("该定时任务类名已存在"); } quartzJobService.saveAndScheduleJob(sysQuartzJob); return Result.ok("创建定时任务成功"); } /** * 更新定时任务 * * @param sysQuartzJob * @return */ @RequestMapping(value = "/edit", method = RequestMethod.PUT) public Result<?> eidt(@RequestBody SysQuartzJob sysQuartzJob) { try { quartzJobService.editAndScheduleJob(sysQuartzJob); } catch (SchedulerException e) { log.error(e.getMessage(),e); return Result.error("更新定时任务失败!"); } return Result.ok("更新定时任务成功!"); } /** * 通过id删除 * * @param id * @return */ @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result<?> delete(@RequestParam(name = "id", required = true) String id) { SysQuartzJob sysQuartzJob = quartzJobService.getById(id); if (sysQuartzJob == null) { return Result.error("未找到对应实体"); } quartzJobService.deleteAndStopJob(sysQuartzJob); return Result.ok("删除成功!"); } /** * 批量删除 * * @param ids * @return */ @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) { if (ids == null || "".equals(ids.trim())) { return Result.error("参数不识别!"); } for (String id : Arrays.asList(ids.split(","))) { SysQuartzJob job = quartzJobService.getById(id); quartzJobService.deleteAndStopJob(job); } return Result.ok("删除定时任务成功!"); } /** * 暂停定时任务 * * @param job * @return */ @GetMapping(value = "/pause") //@ApiOperation(value = "暂停定时任务") public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) { SysQuartzJob job = null; try { job = quartzJobService.getOne(new LambdaQueryWrapper<SysQuartzJob>().eq(SysQuartzJob::getJobClassName, jobClassName)); if (job == null) { return Result.error("定时任务不存在!"); } scheduler.pauseJob(JobKey.jobKey(jobClassName.trim())); } catch (SchedulerException e) { throw new JeecgBootException("暂停定时任务失败"); } job.setStatus(CommonConstant.STATUS_DISABLE); quartzJobService.updateById(job); return Result.ok("暂停定时任务成功"); } /** * 启动定时任务 * * @param job * @return */ @GetMapping(value = "/resume") //@ApiOperation(value = "恢复定时任务") public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) { SysQuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<SysQuartzJob>().eq(SysQuartzJob::getJobClassName, jobClassName)); if (job == null) { return Result.error("定时任务不存在!"); } quartzJobService.resumeJob(job); //scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim())); return Result.ok("恢复定时任务成功"); } /** * 通过id查询 * * @param id * @return */ @RequestMapping(value = "/queryById", method = RequestMethod.GET) public Result<?> queryById(@RequestParam(name = "id", required = true) String id) { SysQuartzJob sysQuartzJob = quartzJobService.getById(id); return Result.ok(sysQuartzJob); } /** * 导出excel * * @param request * @param response */ @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, SysQuartzJob sysQuartzJob) { // Step.1 组装查询条件 QueryWrapper<SysQuartzJob> queryWrapper = QueryGenerator.initQueryWrapper(sysQuartzJob, request.getParameterMap()); // Step.2 AutoPoi 导出Excel ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); List<SysQuartzJob> pageList = quartzJobService.list(queryWrapper); // 导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表"); mv.addObject(NormalExcelConstants.CLASS, SysQuartzJob.class); mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:Jeecg", "导出信息")); mv.addObject(NormalExcelConstants.DATA_LIST, pageList); return mv; } /** * 通过excel导入数据 * * @param request * @param response * @return */ @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { MultipartFile file = entity.getValue();// 获取上传文件对象 ImportParams params = new ImportParams(); params.setTitleRows(2); params.setHeadRows(1); params.setNeedSave(true); try { List<SysQuartzJob> listSysQuartzJobs = ExcelImportUtil.importExcel(file.getInputStream(), SysQuartzJob.class, params); for (SysQuartzJob sysQuartzJobExcel : listSysQuartzJobs) { quartzJobService.save(sysQuartzJobExcel); } return Result.ok("文件导入成功!数据行数:" + listSysQuartzJobs.size()); } catch (Exception e) { log.error(e.getMessage(), e); return Result.error("文件导入失败!"); } finally { try { file.getInputStream().close(); } catch (IOException e) { e.printStackTrace(); } } } return Result.error("文件导入失败!"); } }
7、job定时任务样例
package org.jeecg.modules.quartz.job; import org.jeecg.common.util.DateUtils; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import lombok.extern.slf4j.Slf4j; /** * 示例不带参定时任务 * * @Author Scott */ @Slf4j public class SampleJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info(String.format(" Jeecg-Boot 普通定时任务 SampleJob ! 时间:" + DateUtils.getTimestamp())); } }
分类:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2015-03-02 flex label 换行