• springboot集成Quartzjob存储方式一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()));
        }
    }
  • 相关阅读:
    实战:垂直电商如何撬动“女人腰包”
    谈谈项目收尾
    项目管理心得:一个项目经理的个人体会、经验总结
    IT项目经理沟通技巧的重要性
    项目跟踪:项目跟踪要跟踪什么呢?
    会员营销,你真的做到了吗?
    Git入门——基础知识问答
    文摘:威胁建模(STRIDE方法)
    写在2015年工作的第一天
    简化工作——我的bat文件
  • 原文地址:https://www.cnblogs.com/tiandi/p/15957562.html
Copyright © 2020-2023  润新知