spring-boot整合Quartz-job儲存方式一JDBC
阿新 • • 發佈:2022-03-03
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("檔案匯入失敗!"); } }