spring boot 中使用持久化quartz(与mybatis plus数据源分开)
[TOC]
增加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mysql连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--jdbc依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--quartz定时调度依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
配置文件
spring:
quartz:
job-store-type: jdbc #持久化到数据库
properties:
org:
quartz:
# quartz的MySQL数据源配置
datasource:
# 新版驱动从com.mysql.jdbc.Driver变更为com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
# 数据源需要添加时间标准和指定编码格式解决乱码 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
url: jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: zzq
password: 123
scheduler:
instancName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate说明支持集群
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 1000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 20
threadPriority: 5
#mybatis plus的数据源配置
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
username: zzq
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath:mapper/**.xml
global-config:
db-config:
id-type: auto
创建quartz数据库
创建数据库后执行建表语句
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
commit;
数据源配置
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* @author :zzq
* @version :1.0
* @date :Created in 2021/10/21 16:26
* @description:
* @modified By:
*/
@Configuration
public class DatasourceConfig {
/**
* 功能描述: quartz数据源配置
* @Author: zzq
* @Date: 2021/10/22 10:58
* @Param:
* @Return: javax.sql.DataSource
*/
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
DataSource quartzDataSource(){
return DruidDataSourceBuilder.create().build();
}
/**
* 功能描述: mybatis plus数据源配置
* @Author: zzq
* @Date: 2021/10/22 10:58
* @Param:
* @Return: com.alibaba.druid.pool.DruidDataSource
*/
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
DruidDataSource druidDataSource(){
return DruidDataSourceBuilder.create().build();
}
}
使用案例
modal层
mport com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* @author :zzq
* @version :1.0
* @date :Created in 2021/10/21 16:31
* @description:
* @modified By:
*/
@Data
public class NoticeSettingVo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date time;
private String msg;
private String cron;
}
controller层
import com.example.quartzTest.pojo.vo.NoticeSettingVo;
import com.example.quartzTest.service.NoticeSettingService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author :zzq
* @version :1.0
* @date :Created in 2021/10/22 9:19
* @description:
* @modified By:
*/
@RestController
public class NoticeSettingController {
@Autowired
private NoticeSettingService noticeSettingService;
/**
* 功能描述: 设定通知任务的执行时间
* @Author: zzq
* @Date: 2021/10/22 9:54
* @Param: noticeSettingVo
* @Return: java.lang.String
*/
@PostMapping("noticeSetting")
public String setNoticeSetting(@RequestBody NoticeSettingVo noticeSettingVo){
try {
return noticeSettingService.setNoticeSetting(noticeSettingVo);
} catch (SchedulerException e) {
e.printStackTrace();
return "faille,"+e.getMessage();
}
}
/**
* 功能描述: 获取通知任务的执行时间
* @Author: zzq
* @Date: 2021/10/22 10:51
* @Param:
* @Return: java.util.Map
*/
@GetMapping("noticeSetting")
public Map getNoticeSetting(){
try {
return noticeSettingService.getNoticeSetting();
} catch (SchedulerException e) {
e.printStackTrace();
return null;
}
}
}
service层
import com.example.quartzTest.pojo.vo.NoticeSettingVo;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author :zzq
* @version :1.0
* @date :Created in 2021/10/22 9:19
* @description:
* @modified By:
*/
@Service
public class NoticeSettingService {
@Autowired
private Scheduler scheduler;
/**
* 功能描述: 设定通知任务的执行时间
* @Author: zzq
* @Date: 2021/10/22 9:35
* @Param: noticeAddVo
* @Return: java.lang.String
*/
public String setNoticeSetting(NoticeSettingVo noticeSettingVo) throws SchedulerException {
if (noticeSettingVo.getTime()==null&& noticeSettingVo.getCron()==null) {
// 如果没有输入时间和表达式,则返回错误
return "faille";
}
if (noticeSettingVo.getCron() != null) {
// 如果输入了cron表达式,则进行格式校验
if (!CronExpression.isValidExpression(noticeSettingVo.getCron())) {
return "faille,Illegal cron expression";
}
}
TriggerBuilder<Trigger> triggerTriggerBuilder = TriggerBuilder.newTrigger().withIdentity("notice","system");
if (noticeSettingVo.getCron()!=null) {
// 如果corn不为空,则根据cron表达式设定任务执行时间
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(noticeSettingVo.getCron()).withMisfireHandlingInstructionDoNothing();
if (noticeSettingVo.getTime() != null) {
// 如果指定了时间,则从指定时间开始执行任务
triggerTriggerBuilder.withSchedule(scheduleBuilder).startAt(noticeSettingVo.getTime());
}else {
// 如果未指定时间,则立刻开始执行
triggerTriggerBuilder.withSchedule(scheduleBuilder).startNow();
}
}else {
// 如果没有corn表达式,则按指定时间执行一次任务
triggerTriggerBuilder.startAt(noticeSettingVo.getTime()).withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0));
}
Trigger trigger = triggerTriggerBuilder.build();
if (noticeSettingVo.getMsg() != null) {
// 如果存在msg,则将msg存入dataMap中
trigger.getJobDataMap().put("msg", noticeSettingVo.getMsg());
}
JobKey jobKey = new JobKey("notice","system");
TriggerKey triggerKey = TriggerKey.triggerKey("notice","system");
JobDetail oldJobDetail = scheduler.getJobDetail(jobKey);
if (oldJobDetail != null&&scheduler.checkExists(triggerKey)) {
// 如果该任务已存在,则进行更新操作
scheduler.rescheduleJob(triggerKey,trigger);
}else {
JobDetail jobDetail = JobBuilder.newJob(new Job() {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("当前时间:"+new Date()+",执行了任务Notice,msg为:"+context.getTrigger().getJobDataMap().get("msg"));
}
}.getClass()).withIdentity("notice","system").build();
// 任务不存在则进行添加操作
scheduler.scheduleJob(jobDetail,trigger);
}
return "success";
}
/**
* 功能描述: 获取定时任务的执行时间
* @Author: zzq
* @Date: 2021/10/22 10:52
* @Param:
* @Return: java.util.Map
*/
public Map getNoticeSetting() throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey("notice","system");
// 获取触发器trigger
Trigger trigger = scheduler.getTrigger(triggerKey);
if (trigger == null) {
// 如果任务不存,则返回空
return null;
}
Map<String,Object> res = new HashMap(8);
if (trigger instanceof CronTriggerImpl) {
// 如果是使用cron表达式设定的任务,则返回cron表达式
CronTriggerImpl cronTrigger= (CronTriggerImpl) trigger;
String cronExpression = cronTrigger.getCronExpression();
System.out.println(cronExpression);
res.put("cron",cronExpression);
}
// 返回开始时间
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
res.put("time", df.format(trigger.getStartTime()));
// 返回描述信息
res.put("description",trigger.getDescription());
// 返回dataMap
res.put("dataMap",trigger.getJobDataMap());
return res;
}
}