部分內(nèi)容轉(zhuǎn)載自“爾笑惹千愁”炼列,鏈接https://blog.csdn.net/lx1309244704/article/details/81810373
在我們?nèi)粘5拈_發(fā)中,很多時(shí)候音比,定時(shí)任務(wù)都不是寫死的俭尖,而是寫到數(shù)據(jù)庫中,從而實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)配置洞翩,下面就通過一個(gè)簡(jiǎn)單的示例稽犁,來實(shí)現(xiàn)這個(gè)功能。
一骚亿、添加依賴包
```
<!-- quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
```
二已亥、創(chuàng)建調(diào)度器
```
package com.quartz;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerConfig implements SchedulerFactoryBeanCustomizer{
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setStartupDelay(2);
? ? ? ? schedulerFactoryBean.setAutoStartup(true);
? ? ? ? schedulerFactoryBean.setOverwriteExistingJobs(true);
}
}
```
三、application.yml配置
**這里需要注意的幾點(diǎn):**
**1来屠、如果你的框架是已經(jīng)搭建好虑椎,只需要在yml中添加quartz相關(guān)屬性配置和數(shù)據(jù)庫方式配置**
**2、quartz相關(guān)屬性配置是在spring下管理俱笛,注意縮進(jìn)格式捆姜,如果位置或者縮進(jìn)不對(duì)程序啟動(dòng)后也不會(huì)報(bào)錯(cuò)**
```
server:
? ? port: 8003
# 默認(rèn)的profile為dev,其他環(huán)境通過指定啟動(dòng)參數(shù)使用不同的profile迎膜,比如:?
#? 測(cè)試環(huán)境:java -jar quartz-service.jar --spring.profiles.active=test?
#? 生產(chǎn)環(huán)境:java -jar quartz-service.jar --spring.profiles.active=prod?
spring:
? datasource:
? ? type: com.alibaba.druid.pool.DruidDataSource? #這里是配置druid連接池泥技,以下都是druid的配置信息
? ? url: jdbc:mysql://0.0.0.0:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false
? ? driver-class-name: com.mysql.jdbc.Driver
? ? username: root
? ? password: ******
? quartz:
? ? #相關(guān)屬性配置
? ? properties:
? ? ? org:
? ? ? ? quartz:
? ? ? ? ? scheduler:
? ? ? ? ? ? instanceName: clusteredScheduler
? ? ? ? ? ? instanceId: AUTO
? ? ? ? ? jobStore:
? ? ? ? ? ? class: org.quartz.impl.jdbcjobstore.JobStoreTX
? ? ? ? ? ? driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
? ? ? ? ? ? tablePrefix: QRTZ_
? ? ? ? ? ? isClustered: true
? ? ? ? ? ? clusterCheckinInterval: 10000
? ? ? ? ? ? useProperties: false
? ? ? ? ? threadPool:
? ? ? ? ? ? class: org.quartz.simpl.SimpleThreadPool
? ? ? ? ? ? threadCount: 10
? ? ? ? ? ? threadPriority: 5
? ? ? ? ? ? threadsInheritContextClassLoaderOfInitializingThread: true
? ? #數(shù)據(jù)庫方式
? ? job-store-type: jdbc
mybatis-plus:
? mapper-locations: classpath*:/mapper/**Mapper.xml? ? #把xml文件放在com.XX.mapper.*中可能會(huì)出現(xiàn)找到的問題,這里把他放在resource下的mapper中
? typeAliasesPackage: com.quartz.domain? ? ? ? #這里是實(shí)體類的位置磕仅,#實(shí)體掃描珊豹,多個(gè)package用逗號(hào)或者分號(hào)分隔
? configuration:
? ? map-underscore-to-camel-case: true
? ? cache-enabled: false
logging:
? file: quartz-service.log
? level:
? ? com.quartz: debug?
```
四、JobController
```
package com.south.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.south.data.vo.JobAndTriggerDto;
import com.south.service.IJobAndTriggerService;
import com.south.utils.PaginationUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.List;
/**
* @Classname JobController
* @Description TODO
* @Date 2019/7/31 14:11
* @Created by zhangzhenjun
*/
@Slf4j
@RestController
@RequestMapping("/api")
public class JobResource {
? ? @Autowired
? ? private IJobAndTriggerService jobAndTriggerService;
? ? public JobResource(IJobAndTriggerService jobAndTriggerService){
? ? ? ? this.jobAndTriggerService = jobAndTriggerService;
? ? }
? ? @PostMapping(value = "/datagrid")
? ? public ResponseEntity<List<JobAndTriggerDto>> queryjob(Pageable pageable, @RequestParam MultiValueMap<String, String> queryParams, UriComponentsBuilder uriBuilder) {
? ? ? ? log.debug("queryjob");
? ? ? ? IPage<JobAndTriggerDto> page = jobAndTriggerService.getPageJob(pageable, queryParams);
? ? ? ? HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(uriBuilder.queryParams(queryParams), page);
? ? ? ? return ResponseEntity.ok().headers(headers).body(page.getRecords());
? ? }
? ? /**
? ? * @Title: addJob
? ? * @Description: TODO(添加Job)
? ? * @param jobClassName
? ? *? ? ? ? ? ? 類名
? ? * @param jobGroupName
? ? *? ? ? ? ? ? 組名
? ? * @param cronExpression
? ? *? ? ? ? ? ? 表達(dá)式榕订,如:0/5 * * * * ? (每隔5秒)
? ? */
? ? @PostMapping(value = "/add")
? ? public ResponseEntity addJob(
? ? ? ? ? ? @RequestParam(value = "jobClassName") String jobClassName,
? ? ? ? ? ? @RequestParam(value = "jobGroupName") String jobGroupName,
? ? ? ? ? ? @RequestParam(value = "cronExpression") String cronExpression){
? ? ? ? try {
? ? ? ? ? ? jobAndTriggerService.addJob(jobClassName, jobGroupName, cronExpression);
? ? ? ? ? ? return ResponseEntity.ok().body("操作成功");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return ResponseEntity.ok().body("操作失敗");
? ? ? ? }
? ? }
? ? /**
? ? * @Title: pauseJob
? ? * @Description: TODO(暫停Job)
? ? * @param jobClassName
? ? *? ? ? ? ? ? 類名
? ? * @param jobGroupName
? ? *? ? ? ? ? ? 組名
? ? */
? ? @PostMapping(value = "/pause")
? ? public ResponseEntity pauseJob(
? ? ? ? ? ? @RequestParam(value = "jobClassName") String jobClassName,
? ? ? ? ? ? @RequestParam(value = "jobGroupName") String jobGroupName) {
? ? ? ? try {
? ? ? ? ? ? jobAndTriggerService.pauseJob(jobClassName, jobGroupName);
? ? ? ? ? ? return ResponseEntity.ok().body("操作成功");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return ResponseEntity.ok().body("操作失敗");
? ? ? ? }
? ? }
? ? /**
? ? * @Title: resumeJob
? ? * @Description: TODO(恢復(fù)Job)
? ? * @param jobClassName
? ? *? ? ? ? ? ? 類名
? ? * @param jobGroupName
? ? *? ? ? ? ? ? 組名
? ? */
? ? @PostMapping(value = "/resume")
? ? public ResponseEntity resumeJob(
? ? ? ? ? ? @RequestParam(value = "jobClassName") String jobClassName,
? ? ? ? ? ? @RequestParam(value = "jobGroupName") String jobGroupName) {
? ? ? ? try {
? ? ? ? ? ? jobAndTriggerService.resumejob(jobClassName, jobGroupName);
? ? ? ? ? ? return ResponseEntity.ok().body("操作成功");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return ResponseEntity.ok().body("操作失敗");
? ? ? ? }
? ? }
? ? /**
? ? * @Title: rescheduleJob
? ? * @Description: TODO(重新設(shè)置Job)
? ? * @param jobClassName
? ? *? ? ? ? ? ? 類名
? ? * @param jobGroupName
? ? *? ? ? ? ? ? 組名
? ? * @param cronExpression
? ? *? ? ? ? ? ? 表達(dá)式
? ? */
? ? @PostMapping(value = "/reschedule")
? ? public ResponseEntity rescheduleJob(
? ? ? ? ? ? @RequestParam(value = "jobClassName") String jobClassName,
? ? ? ? ? ? @RequestParam(value = "jobGroupName") String jobGroupName,
? ? ? ? ? ? @RequestParam(value = "cronExpression") String cronExpression) {
? ? ? ? try {
? ? ? ? ? ? jobAndTriggerService.updateJob(jobClassName, jobGroupName, cronExpression);
? ? ? ? ? ? return ResponseEntity.ok().body("操作成功");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return ResponseEntity.ok().body("操作失敗");
? ? ? ? }
? ? }
? ? /**
? ? * @Title: deleteJob
? ? * @Description: TODO(刪除Job)
? ? * @param jobClassName
? ? *? ? ? ? ? ? 類名
? ? * @param jobGroupName
? ? *? ? ? ? ? ? 組名
? ? */
? ? @RequestMapping(value = "/del", method = RequestMethod.POST)
? ? public ResponseEntity deleteJob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) {
? ? ? ? try {
? ? ? ? ? ? jobAndTriggerService.deleteJob(jobClassName, jobGroupName);
? ? ? ? ? ? return ResponseEntity.ok().body("操作成功");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? return ResponseEntity.ok().body("操作失敗");
? ? ? ? }
? ? }
}
```
五店茶、IJobAndTriggerService
```
package com.south.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.south.data.vo.JobAndTriggerDto;
import org.springframework.data.domain.Pageable;
import org.springframework.util.MultiValueMap;
import java.util.Map;
/**
* @Classname IJobAndTriggerService
* @Description TODO
* @Date 2019/7/31 14:15
* @Created by zhangzhenjun
*/
public interface IJobAndTriggerService extends IService<JobAndTriggerDto> {
? ? /**
? ? * @Title: getPageJob
? ? * @Description: TODO(查詢定時(shí)任務(wù),分頁)
? ? * @param @param search
? ? * @param @return? ? 參數(shù)
? ? * @return Map<String,Object>? ? 返回類型
? ? * @throws
? ? */
? ? IPage<JobAndTriggerDto> getPageJob(Pageable pageable, MultiValueMap queryParam);
? ? /**
? ? * @Title: getPageJobmod
? ? * @Description: TODO(查詢定時(shí)任務(wù))
? ? * @param @return? ? 參數(shù)
? ? * @return JobAndTriggerDto? ? 返回類型
? ? * @throws
? ? */
? ? JobAndTriggerDto getPageJobmod();
? ? /**
? ? * @Title: addJob
? ? * @Description: TODO(添加任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @param cronExpression cron時(shí)間規(guī)則
? ? * @param @throws Exception? ? 參數(shù)
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void addJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception;
? ? /**
? ? * @Title: addJob
? ? * @Description: TODO(添加動(dòng)態(tài)任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @param cronExpression cron時(shí)間規(guī)則
? ? * @param @param jobDescription 參數(shù)
? ? * @param @param params
? ? * @param @throws Exception? 參數(shù)說明
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void addJob(String jobClassName, String jobGroupName, String cronExpression, String jobDescription, Map<String, Object> params) throws Exception;
? ? /**
? ? * @Title: updateJob
? ? * @Description: TODO(更新定時(shí)任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @param cronExpression cron時(shí)間規(guī)則
? ? * @param @throws Exception? ? 參數(shù)
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void updateJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception;
? ? /**
? ? * @Title: deleteJob
? ? * @Description: TODO(刪除定時(shí)任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @throws Exception? ? 參數(shù)
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void deleteJob(String jobClassName, String jobGroupName) throws Exception;
? ? /**
? ? * @Title: pauseJob
? ? * @Description: TODO(暫停定時(shí)任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @throws Exception? ? 參數(shù)
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void pauseJob(String jobClassName, String jobGroupName) throws Exception;
? ? /**
? ? * @Title: resumejob
? ? * @Description: TODO(恢復(fù)任務(wù))
? ? * @param @param jobClassName 任務(wù)路徑名稱
? ? * @param @param jobGroupName 任務(wù)分組
? ? * @param @throws Exception? ? 參數(shù)
? ? * @return void? ? 返回類型
? ? * @throws
? ? */
? ? void resumejob(String jobClassName, String jobGroupName) throws Exception;
}
```
六卸亮、IJobAndTriggerServiceImpl
```
package com.south.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.south.data.mapper.JobAndTriggerMapper;
import com.south.data.vo.JobAndTriggerDto;
import com.south.job.BaseJob;
import com.south.service.IJobAndTriggerService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.CronTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import java.util.Iterator;
import java.util.Map;
/**
* @Classname IJobAndTriggerServiceImpl
* @Description TODO
* @Date 2019/7/31 14:30
* @Created by zhangzhenjun
*/
@Slf4j
@Service
@Transactional
public class IJobAndTriggerServiceImpl extends ServiceImpl<JobAndTriggerMapper, JobAndTriggerDto> implements IJobAndTriggerService {
? ? @Autowired
? ? private Scheduler scheduler;
? ? @Override
? ? public IPage<JobAndTriggerDto> getPageJob(Pageable pageable, MultiValueMap queryParam) {
? ? ? ? IPage<JobAndTriggerDto> page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
? ? ? ? return baseMapper.getJobAndTriggerDetails(page);
? ? }
? ? @Override
? ? public JobAndTriggerDto getPageJobmod() {
? ? ? ? return baseMapper.getJobAndTriggerDto();
? ? }
? ? @Override
? ? public void addJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
? ? ? ? // 啟動(dòng)調(diào)度器
? ? ? ? scheduler.start();
? ? ? ? // 構(gòu)建job信息
? ? ? ? JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
? ? ? ? ? ? ? ? .withIdentity(jobClassName, jobGroupName).build();
? ? ? ? // 表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)
? ? ? ? CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
? ? ? ? // 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger
? ? ? ? CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
? ? ? ? ? ? ? ? .withSchedule(scheduleBuilder).build();
? ? ? ? try {
? ? ? ? ? ? scheduler.scheduleJob(jobDetail, trigger);
? ? ? ? ? ? System.out.println("創(chuàng)建定時(shí)任務(wù)成功");
? ? ? ? } catch (SchedulerException e) {
? ? ? ? ? ? System.out.println("創(chuàng)建定時(shí)任務(wù)失敗" + e);
? ? ? ? ? ? throw new Exception("創(chuàng)建定時(shí)任務(wù)失敗");
? ? ? ? }
? ? }
? ? @Override
? ? public void addJob(String jobClassName, String jobGroupName, String cronExpression, String jobDescription,
? ? ? ? ? ? ? ? ? ? ? Map<String, Object> params) throws Exception {
? ? ? ? // 啟動(dòng)調(diào)度器
? ? ? ? scheduler.start();
? ? ? ? // 構(gòu)建job信息
? ? ? ? JobDetail jobDetail = JobBuilder.newJob(IJobAndTriggerServiceImpl.getClass(jobClassName).getClass())
? ? ? ? ? ? ? ? .withIdentity(jobClassName, jobGroupName).withDescription(jobDescription).build();
? ? ? ? Iterator<Map.Entry<String, Object>> var7 = params.entrySet().iterator();
? ? ? ? while(var7.hasNext()) {
? ? ? ? ? ? Map.Entry<String, Object> entry = var7.next();
? ? ? ? ? ? jobDetail.getJobDataMap().put((String)entry.getKey(), entry.getValue());
? ? ? ? }
? ? ? ? System.out.println("jobDetail數(shù)據(jù):--------"+jobDetail.toString());
? ? ? ? // 表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)
? ? ? ? CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
? ? ? ? // 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger
? ? ? ? CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
? ? ? ? ? ? ? ? .withSchedule(scheduleBuilder).build();
? ? ? ? try {
? ? ? ? ? ? scheduler.scheduleJob(jobDetail, trigger);
? ? ? ? ? ? System.out.println("創(chuàng)建定時(shí)任務(wù)成功");
? ? ? ? } catch (SchedulerException e) {
? ? ? ? ? ? System.out.println("創(chuàng)建定時(shí)任務(wù)失敗" + e);
? ? ? ? ? ? throw new Exception("創(chuàng)建定時(shí)任務(wù)失敗");
? ? ? ? }
? ? }
? ? @Override
? ? public void updateJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception {
? ? ? ? try {
? ? ? ? ? ? TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
? ? ? ? ? ? // 表達(dá)式調(diào)度構(gòu)建器(動(dòng)態(tài)修改后不立即執(zhí)行)
? ? ? ? ? ? CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
? ? ? ? ? ? CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
? ? ? ? ? ? // 按新的cronExpression表達(dá)式重新構(gòu)建trigger
? ? ? ? ? ? trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
? ? ? ? ? ? // 按新的trigger重新設(shè)置job執(zhí)行
? ? ? ? ? ? scheduler.rescheduleJob(triggerKey, trigger);
? ? ? ? } catch (SchedulerException e) {
? ? ? ? ? ? System.out.println("更新定時(shí)任務(wù)失敗" + e);
? ? ? ? ? ? throw new Exception("更新定時(shí)任務(wù)失敗");
? ? ? ? }
? ? }
? ? @Override
? ? public void deleteJob(String jobClassName, String jobGroupName) throws Exception {
? ? ? ? scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));
? ? ? ? scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));
? ? ? ? scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
? ? }
? ? @Override
? ? public void pauseJob(String jobClassName, String jobGroupName) throws Exception {
? ? ? ? scheduler.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
? ? }
? ? @Override
? ? public void resumejob(String jobClassName, String jobGroupName) throws Exception {
? ? ? ? scheduler.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
? ? }
? ? public static BaseJob getClass(String classname) throws Exception {
? ? ? ? Class<?> class1 = Class.forName(classname);
? ? ? ? return (BaseJob) class1.newInstance();
? ? }
}
```
七忽妒、JobAndTriggerMapper
```
package com.south.data.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.south.data.vo.JobAndTriggerDto;
/**
* @Classname JobAndTriggerMapper
* @Description TODO
* @Date 2019/7/31 14:31
* @Created by zhangzhenjun
*/
public interface JobAndTriggerMapper extends BaseMapper<JobAndTriggerDto> {
? ? IPage<JobAndTriggerDto> getJobAndTriggerDetails(IPage<JobAndTriggerDto> page);
? ? JobAndTriggerDto getJobAndTriggerDto();
}
```
八、JobAndTriggerMapper.xml
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.south.data.mapper.JobAndTriggerMapper">
? ? <select id="getJobAndTriggerDetails" resultType="com.south.data.vo.JobAndTriggerDto">
SELECT
jd.JOB_NAME AS jobName,
jd.DESCRIPTION AS jobDescription,
jd.JOB_GROUP AS jobGroupName,
jd.JOB_CLASS_NAME AS jobClassName,
t.TRIGGER_NAME AS triggerName,
t.TRIGGER_GROUP AS triggerGroupName,
FROM_UNIXTIME(t.PREV_FIRE_TIME/1000,'%Y-%m-%d %T') AS prevFireTime,
FROM_UNIXTIME(t.NEXT_FIRE_TIME/1000,'%Y-%m-%d %T') AS nextFireTime,
ct.CRON_EXPRESSION AS cronExpression,
t.TRIGGER_STATE AS triggerState
FROM
qrtz_job_details jd
JOIN qrtz_triggers t
JOIN qrtz_cron_triggers ct ON jd.JOB_NAME = t.JOB_NAME
AND t.TRIGGER_NAME = ct.TRIGGER_NAME
AND t.TRIGGER_GROUP = ct.TRIGGER_GROUP
? ? </select>
? ? <select id="getJobAndTriggerDto" resultType="com.south.data.vo.JobAndTriggerDto">
SELECT
jd.JOB_NAME AS jobName,
jd.DESCRIPTION AS jobDescription,
jd.JOB_GROUP AS jobGroupName,
jd.JOB_CLASS_NAME AS jobClassName,
t.TRIGGER_NAME AS triggerName,
t.TRIGGER_GROUP AS triggerGroupName,
FROM_UNIXTIME(t.PREV_FIRE_TIME/1000,'%Y-%m-%d %T') AS prevFireTime,
FROM_UNIXTIME(t.NEXT_FIRE_TIME/1000,'%Y-%m-%d %T') AS nextFireTime,
ct.CRON_EXPRESSION AS cronExpression,
t.TRIGGER_STATE AS triggerState
FROM
qrtz_job_details jd
JOIN qrtz_triggers t
JOIN qrtz_cron_triggers ct ON jd.JOB_NAME = t.JOB_NAME
AND t.TRIGGER_NAME = ct.TRIGGER_NAME
AND t.TRIGGER_GROUP = ct.TRIGGER_GROUP
? ? </select>
</mapper>
```
九、BaseJob
```
package com.south.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* @Classname BaseJob
* @Description TODO
* @Date 2019/7/31 14:52
* @Created by zhangzhenjun
*/
public interface BaseJob extends Job {
? public void execute(JobExecutionContext context) throws JobExecutionException;
}
```
十段直、HelloJob實(shí)例吃溅,在這里面寫定時(shí)任務(wù)要執(zhí)行的內(nèi)容
```
package com.south.job;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/**
* @Classname HelloJob
* @Description TODO
* @Date 2019/7/31 14:10
* @Created by zhangzhenjun
*/
@Slf4j
public class HelloJob implements BaseJob {
? ? @Override
? ? public void execute(JobExecutionContext context) throws JobExecutionException {
? ? ? ? log.error("Hello Job執(zhí)行時(shí)間: " + new Date());
? ? ? ? System.err.println("Hello Job執(zhí)行時(shí)間: " + new Date());
? ? }?
}?
```
十一、啟動(dòng)類加上@EnableScheduling注解鸯檬,在項(xiàng)目啟動(dòng)時(shí)加載定時(shí)任務(wù)决侈,啟動(dòng)Job
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190802091619840.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNTY3ODAx,size_16,color_FFFFFF,t_70)
項(xiàng)目效果:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/2019080209184473.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNTY3ODAx,size_16,color_FFFFFF,t_70)
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190802091904900.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNTY3ODAx,size_16,color_FFFFFF,t_70)
如果需要源碼,請(qǐng)?zhí)D(zhuǎn)自本博文最上方的轉(zhuǎn)載鏈接喧务;
***最后再附上Java轉(zhuǎn)Cron表達(dá)式的工具類赖歌,具體代碼在我的另一篇博文:java生成cron表達(dá)式***
***鏈接:https://blog.csdn.net/qq_42567801/article/details/98172088***