数据表 加不加无所谓,如果需要重启服务器后重新执行所有JOB就把sql加上
如果不加表 将application.properties中的quartz数据库配置去掉
自己执行自己的逻辑来就好,大不了每次启动之后重新加载自己的逻辑
链接:https://pan.baidu.com/s/1KqOPYMfI4eHcEMxt5BmtYg
提取码:o9ql
--来自百度网盘超级会员V4的分享
SpringBoot工程
pom依赖
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- </dependency>-->
<!--解决加了@ConfigurationProperties注解 类上的提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
application.properties
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/job3?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=123456
#
#
#
#mybatis-plus.configuration.map-underscore-to-camel-case=true
#
#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#
#
#mybatis-plus.global-config.db-config.table-prefix=tbl_
#
#
#mybatis-plus.global-config.db-config.id-type=auto
# 定时任务Quartz的数据源配置
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.URL=jdbc:mysql://localhost:3306/job3?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.driver=com.mysql.cj.jdbc.Driver
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.maxConnections=5
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.username=root
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.password=123456
spring.quartz.properties.org.quartz.dataSource.globalJobDataSource.provider=hikaricp
# Quartz调度器配置
spring.quartz.properties.org.quartz.scheduler.instanceName=globalScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.scheduler.type=com.alibaba.druid.pool.DruidDataSource
# Quartz作业存储配置
spring.quartz.properties.org.quartz.jobStore.dataSource=globalJobDataSource
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=100
spring.quartz.properties.org.quartz.jobStore.isClustered=true
# Quartz线程池配置
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount=10
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
包结构
实体类
package com.example.springbootquartz.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author hrui
* @date 2023/11/16 22:57
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class JobInfo {
/**
* 任务名称
*/
private String jobName;
/**
* 任务组
*/
private String jobGroup;
/**
* 触发器名称
*/
private String triggerName;
/**
* 触发器组
*/
private String triggerGroup;
/**
* cron表达式
*/
private String cron;
/**
* 类名
*/
private String className;
/**
* 状态
*/
private String status;
/**
* 下一次执行时间
*/
private String nextTime;
/**
* 上一次执行时间
*/
private String prevTime;
/**
* 配置信息(data)
*/
private String config;
}
package com.example.springbootquartz.job;
import com.alibaba.fastjson.JSONObject;
import com.example.springbootquartz.pojo.JobInfo;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
/**
* @author hrui
* @date 2023/11/16 23:10
*/
@Component
public class SchedulerManage {
@Autowired
private Scheduler scheduler;
/**
* 添加任务
*/
@SuppressWarnings("unchecked")
public void addJob(JobInfo jobInfo) throws SchedulerException, ClassNotFoundException {
Objects.requireNonNull(jobInfo, "任务信息不能为空");
// 生成job key
JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
// 当前任务不存在才进行添加
if (!scheduler.checkExists(jobKey)) {
Class<Job> jobClass = (Class<Job>)Class.forName(jobInfo.getClassName());
// 任务明细
JobDetail jobDetail = JobBuilder
.newJob(jobClass)
.withIdentity(jobKey)
.withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup())
.withDescription(jobInfo.getJobName())
.build();
// 配置信息
jobDetail.getJobDataMap().put("config", jobInfo.getConfig());
// 定义触发器
TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
// 设置任务的触发机制
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobInfo.getCron()).withMisfireHandlingInstructionDoNothing())
.build();
scheduler.scheduleJob(jobDetail, trigger);
} else {
throw new SchedulerException(jobInfo.getJobName() + "任务已存在,无需重复添加");
}
}
/**
* 任务暂停
*/
public void pauseJob(String jobGroup, String jobName) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
if (scheduler.checkExists(jobKey)) {
scheduler.pauseJob(jobKey);
}
}
/**
* 继续任务
*/
public void continueJob(String jobGroup, String jobName) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
if (scheduler.checkExists(jobKey)) {
scheduler.resumeJob(jobKey);
}
}
/**
* 删除任务
*/
public boolean deleteJob(String jobGroup, String jobName) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
if (scheduler.checkExists(jobKey)) {
// 这里还需要先删除trigger相关
//TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup());
//scheduler.getTrigger()
//scheduler.rescheduleJob()
return scheduler.deleteJob(jobKey);//不需要删除trigger 一个job可以有多个trigger 删除job同时源码底层会删除对应trigger
}
return false;
}
/**
* 获取任务信息
*/
public JobInfo getJobInfo(String jobGroup, String jobName) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
if (!scheduler.checkExists(jobKey)) {
return null;
}
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
if (Objects.isNull(triggers)) {
throw new SchedulerException("未获取到触发器信息");
}
TriggerKey triggerKey = triggers.get(0).getKey();
Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
JobInfo jobInfo = new JobInfo();
jobInfo.setJobName(jobGroup);
jobInfo.setJobGroup(jobName);
jobInfo.setTriggerName(triggerKey.getName());
jobInfo.setTriggerGroup(triggerKey.getGroup());
jobInfo.setClassName(jobDetail.getJobClass().getName());
jobInfo.setStatus(triggerState.toString());
if (Objects.nonNull(jobDetail.getJobDataMap())) {
jobInfo.setConfig(JSONObject.toJSONString(jobDetail.getJobDataMap()));
}
CronTrigger theTrigger = (CronTrigger) triggers.get(0);
jobInfo.setCron(theTrigger.getCronExpression());
return jobInfo;
}
}
package com.example.springbootquartz.job;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author hrui
* @date 2023/11/16 22:58
*/
@DisallowConcurrentExecution//避免并发执行
@PersistJobDataAfterExecution//Job状态
public class QuartzJob1 extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) {
System.out.println("QuartzJob1正在执行..."+getTime());
}
private String getTime(){
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
return dateFormat.format(new Date());
}
}
控制器
package com.example.springbootquartz.controller;
import com.example.springbootquartz.job.SchedulerManage;
import com.example.springbootquartz.pojo.JobInfo;
import org.quartz.*;
import org.quartz.impl.StdScheduler;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author hrui
* @date 2023/11/16 23:13
*/
@RestController
@RequestMapping("/job")
public class QuartzController {
@Autowired
private SchedulerManage schedulerManage;
@Autowired
private Scheduler scheduler;
//StdScheduler
@Autowired
private SchedulerFactoryBean SchedulerFactoryBean;
/**
* 查询所有的任务
*/
@RequestMapping("/all")
public List<JobInfo> list() throws SchedulerException {
List<JobInfo> jobInfos = new ArrayList<>();
List<String> triggerGroupNames = scheduler.getTriggerGroupNames();
for (String triggerGroupName : triggerGroupNames) {
Set<TriggerKey> triggerKeySet = scheduler
.getTriggerKeys(GroupMatcher.triggerGroupEquals(triggerGroupName));
for (TriggerKey triggerKey : triggerKeySet) {
Trigger trigger = scheduler.getTrigger(triggerKey);
JobKey jobKey = trigger.getJobKey();
JobInfo jobInfo = schedulerManage.getJobInfo(jobKey.getGroup(), jobKey.getName());
jobInfos.add(jobInfo);
}
}
return jobInfos;
}
/**
* 添加任务
*/
@PostMapping("/add")
public JobInfo addJob(@RequestBody JobInfo jobInfo) throws SchedulerException, ClassNotFoundException {
schedulerManage.addJob(jobInfo);
return jobInfo;
}
/**
* 暂停任务
*/
@RequestMapping("/pause")
public void pauseJob(@RequestParam("jobGroup") String jobGroup, @RequestParam("jobName") String jobName)
throws SchedulerException {
schedulerManage.pauseJob(jobGroup, jobName);
}
/**
* 继续任务
*/
@RequestMapping("/continue")
public void continueJob(@RequestParam("jobGroup") String jobGroup, @RequestParam("jobName") String jobName)
throws SchedulerException {
schedulerManage.continueJob(jobGroup, jobName);
}
/**
* 删除任务
*/
@RequestMapping("/delete")
public boolean deleteJob(@RequestParam("jobGroup") String jobGroup, @RequestParam("jobName") String jobName)
throws SchedulerException {
return schedulerManage.deleteJob(jobGroup, jobName);
}
}
{
"jobName":"job1",
"jobGroup":"group1",
"triggerName":"trigger1",
"triggerGroup":"tGroup1",
"cron":"*/5 * * * * ?",
"className":"com.example.springbootquartz.job.QuartzJob1"
}