Spring整合Quartz

a、quartz调度框架是有内置表的

进入quartz的官网http://www.quartz-scheduler.org/,点击Downloads,

下载后在目录\docs\dbTables下有常用数据库创建quartz表的脚本,例如:

导入pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2..RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jt</groupId>
<artifactId>quartz02</artifactId>
<version>0.0.-SNAPSHOT</version>
<name>quartz02</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <!--quartz-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> <build>
<resources>
<!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
<include>*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<dependencies>
<!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build> </project>

自定义的业务表

-- 注意:job_name存放的任务类的全路径,在quartz中通过jobName和jobGroup来确定trigger的唯一性,所以这两列为联合唯一索引
create table t_schedule_trigger
(
id int primary key auto_increment, -- ID
cron varchar() not null, -- 时间表达式
status char() not null, -- 使用状态 :禁用 :启用
job_name varchar() not null, -- 任务名称
job_group varchar() not null, -- 任务分组
unique index(job_name,job_group)
); -- 额外添加到任务中的参数
create table t_schedule_trigger_param
(
param_id int primary key auto_increment, -- ID
name varchar() not null, -- 参数名
value varchar(), -- 参数值 schedule_trigger_id int not null, -- 外键:引用t_schedule_trigger(id)
foreign key(schedule_trigger_id) references t_schedule_trigger(id)
);

导入DruidConnectionProvider.java

package com.jt.quartz02.util;

import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.SchedulerException;
import org.quartz.utils.ConnectionProvider; import java.sql.Connection;
import java.sql.SQLException; /*
#============================================================================
# JDBC
#============================================================================
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:false
org.quartz.jobStore.dataSource:qzDS
#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider
org.quartz.dataSource.qzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProvider
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnections:30
org.quartz.dataSource.qzDS.validationQuery: select 0
*/ /**
* [Druid连接池的Quartz扩展类]
*/
public class DruidConnectionProvider implements ConnectionProvider { /*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 常量配置,与quartz.properties文件的key保持一致(去掉前缀),同时提供set方法,Quartz框架自动注入值。
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/ //JDBC驱动
public String driver;
//JDBC连接串
public String URL;
//数据库用户名
public String user;
//数据库用户密码
public String password;
//数据库最大连接数
public int maxConnection;
//数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。
public String validationQuery; private boolean validateOnCheckout; private int idleConnectionValidationSeconds; public String maxCachedStatementsPerConnection; private String discardIdleConnectionsSeconds; public static final int DEFAULT_DB_MAX_CONNECTIONS = ; public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = ; //Druid连接池
private DruidDataSource datasource; /*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 接口实现
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public Connection getConnection() throws SQLException {
return datasource.getConnection();
} public void shutdown() throws SQLException {
datasource.close();
}
public void initialize() throws SQLException{
if (this.URL == null) {
throw new SQLException("DBPool could not be created: DB URL cannot be null");
} if (this.driver == null) {
throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");
} if (this.maxConnection < ) {
throw new SQLException("DBPool maxConnectins could not be created: Max connections must be greater than zero!");
} datasource = new DruidDataSource();
try{
datasource.setDriverClassName(this.driver);
} catch (Exception e) {
try {
throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);
} catch (SchedulerException e1) {
}
} datasource.setUrl(this.URL);
datasource.setUsername(this.user);
datasource.setPassword(this.password);
datasource.setMaxActive(this.maxConnection);
datasource.setMinIdle();
datasource.setMaxWait();
datasource.setMaxPoolPreparedStatementPerConnectionSize(this.DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION); if (this.validationQuery != null) {
datasource.setValidationQuery(this.validationQuery);
if(!this.validateOnCheckout)
datasource.setTestOnReturn(true);
else
datasource.setTestOnBorrow(true);
datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);
}
} /*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 提供get set方法
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public String getDriver() {
return driver;
} public void setDriver(String driver) {
this.driver = driver;
} public String getURL() {
return URL;
} public void setURL(String URL) {
this.URL = URL;
} public String getUser() {
return user;
} public void setUser(String user) {
this.user = user;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public int getMaxConnection() {
return maxConnection;
} public void setMaxConnection(int maxConnection) {
this.maxConnection = maxConnection;
} public String getValidationQuery() {
return validationQuery;
} public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
} public boolean isValidateOnCheckout() {
return validateOnCheckout;
} public void setValidateOnCheckout(boolean validateOnCheckout) {
this.validateOnCheckout = validateOnCheckout;
} public int getIdleConnectionValidationSeconds() {
return idleConnectionValidationSeconds;
} public void setIdleConnectionValidationSeconds(int idleConnectionValidationSeconds) {
this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;
} public DruidDataSource getDatasource() {
return datasource;
} public void setDatasource(DruidDataSource datasource) {
this.datasource = datasource;
}
}

quartz.properties

#
#============================================================================
# Configure Main Scheduler Properties \u8C03\u5EA6\u5668\u5C5E\u6027
#============================================================================
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=
org.quartz.threadPool.threadPriority:
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold:
#============================================================================
# Configure JobStore
#============================================================================
#\u5B58\u50A8\u65B9\u5F0F\u4F7F\u7528JobStoreTX\uFF0C\u4E5F\u5C31\u662F\u6570\u636E\u5E93
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#\u4F7F\u7528\u81EA\u5DF1\u7684\u914D\u7F6E\u6587\u4EF6
org.quartz.jobStore.useProperties:true
#\u6570\u636E\u5E93\u4E2Dquartz\u8868\u7684\u8868\u540D\u524D\u7F00
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS
#\u662F\u5426\u4F7F\u7528\u96C6\u7FA4\uFF08\u5982\u679C\u9879\u76EE\u53EA\u90E8\u7F72\u5230 \u4E00\u53F0\u670D\u52A1\u5668\uFF0C\u5C31\u4E0D\u7528\u4E86\uFF09
org.quartz.jobStore.isClustered = true
#============================================================================
# Configure Datasources
#============================================================================
#\u914D\u7F6E\u6570\u636E\u5E93\u6E90
org.quartz.dataSource.qzDS.connectionProvider.class: com.jt.quartz02.util.DruidConnectionProvider
org.quartz.dataSource.qzDS.driver: com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL: jdbc:mysql://localhost:3306/xm1?useUnicode=true&characterEncoding=utf8
org.quartz.dataSource.qzDS.user: root
org.quartz.dataSource.qzDS.password:
org.quartz.dataSource.qzDS.maxConnection:

MyJobFactory.java

package com.jt.quartz02.quartz;

import lombok.extern.slf4j.Slf4j;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component; @Component
@Slf4j
public class MyJobFactory extends AdaptableJobFactory {
//这个对象Spring会帮我们自动注入进来
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory; //重写创建Job任务的实例方法
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//获取quartz框架的任务实例
Object jobInstance = super.createJobInstance(bundle);
//通过以下方式,解决Job任务无法使用Spring中的Bean问题
autowireCapableBeanFactory.autowireBean(jobInstance);
return jobInstance;
} }

QuartzConfiguration.java(quartz调度框架与spring框架整合的配置类,主要是要将org.quartz.Scheduler交给spring进行管理)

package com.jt.quartz02.quartz;

import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean; import java.io.IOException;
import java.util.Properties; /**
* 创建配置类
*/
@Configuration
public class QuartzConfiguration { @Autowired
private MyJobFactory myJobFactory; @Bean
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean sc=new SchedulerFactoryBean();
try {
//加载自定义的quartz.properties文件
sc.setQuartzProperties(quartzProperties());
//设置自定义的JobFactory工程类,解决Spring不能再Quartz框架中Bean的注入问题
sc.setJobFactory(myJobFactory);
return sc;
} catch (IOException e) {
throw new RuntimeException(e);
}
} //指定quartz.properties
@Bean
public Properties quartzProperties() throws IOException {
//创建Properties属性工厂Bean类
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
//加载自定义的quartz.properties
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
} //创建schedule
@Bean(name = "scheduler")
public Scheduler scheduler() {
//从调度器工厂Bean中获取调取度实例对象
return schedulerFactoryBean().getScheduler();
}
}

案例中需要观察表数据变化的表

-- 自定义的业务表
SELECT * FROM t_schedule_trigger;
SELECT * FROM t_schedule_trigger_param; -- quartz调度框架自带的表
SELECT * FROM qrtz_scheduler_state;
SELECT * FROM qrtz_cron_triggers;
SELECT * FROM qrtz_simple_triggers
SELECT * FROM qrtz_triggers;
SELECT * FROM qrtz_job_details;

application.yml

server:
port:
servlet:
context-path: /
spring:
datasource:
#.JDBC
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/xm1?useUnicode=true&characterEncoding=utf8
username: root
password:
druid:
#.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size:
min-idle:
max-active:
#配置获取连接等待超时的时间
max-wait:
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis:
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis:
validation-query: SELECT FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size:
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis:
#.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1 #mybatis配置
mybatis:
#配置SQL映射文件路径
mapper-locations: classpath:mapper/*.xml
#驼峰命名
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.jt.quartz02.mapper: debug #deny: 192.168.1.100
Quartz02Application
package com.jt.quartz02;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication
@MapperScan("com.jt.quartz02.mapper")
@EnableTransactionManagement
@EnableScheduling
public class Quartz02Application {
public static void main(String[] args) {
SpringApplication.run(Quartz02Application.class, args);
} }

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
<!-- 引入配置文件 -->
<properties resource="jdbc.properties"/> <!--指定数据库jdbc驱动jar包的位置-->
<classPathEntry location="D:\repository\mvn-repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
<!-- 一个数据库一个context -->
<context id="infoGuardian">
<!-- 注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
<property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
</commentGenerator> <!-- jdbc连接 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/> <!-- 类型转换 -->
<javaTypeResolver>
<!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver> <!-- 指定javaBean生成的位置 -->
<!-- targetPackage:指定生成的model生成所在的包名 -->
<!-- targetProject:指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="com.jt.quartz02.model"
targetProject="src/main/java">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
<!-- 是否对model添加构造函数 -->
<property name="constructorBased" value="true"/>
<!-- 是否针对string类型的字段在set的时候进行trim调用 -->
<property name="trimStrings" value="false"/>
<!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
<property name="immutable" value="false"/>
</javaModelGenerator> <!-- 指定sql映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.jt.quartz02.mapper"
targetProject="src/main/java">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator> <!-- 生成XxxMapper接口 -->
<!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 -->
<!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 -->
<!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
<javaClientGenerator targetPackage="com.jt.quartz02.mapper"
targetProject="src/main/java" type="XMLMAPPER">
<!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator> <!-- 配置表信息 -->
<!-- schema即为数据库名 -->
<!-- tableName为对应的数据库表 -->
<!-- domainObjectName是要生成的实体类 -->
<!-- enable*ByExample是否生成 example类 -->
<!--<table schema="" tableName="t_book" domainObjectName="Book"-->
<!--enableCountByExample="false" enableDeleteByExample="false"-->
<!--enableSelectByExample="false" enableUpdateByExample="false">-->
<!--&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;-->
<!--&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;-->
<!--&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;-->
<!--&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;-->
<!--</table>--> <!-- <table schema="" tableName="t_schedule_trigger" domainObjectName="ScheduleTtrigger"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" enableUpdateByExample="false">
&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;
&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;
&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;
&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;
</table>
<table schema="" tableName="t_schedule_trigger_param" domainObjectName="ScheduleTriggerParam"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" enableUpdateByExample="false">
&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;
&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;
&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;
&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;
</table>--> </context>
</generatorConfiguration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xm1?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=

ScheduleTtriggerMapper

package com.jt.quartz02.mapper;

import com.jt.quartz02.model.ScheduleTtrigger;
import org.springframework.stereotype.Repository; import java.util.List; @Repository
public interface ScheduleTtriggerMapper {
int deleteByPrimaryKey(Integer id); int insert(ScheduleTrigger record); int insertSelective(ScheduleTrigger record); ScheduleTrigger selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(ScheduleTrigger record); int updateByPrimaryKey(ScheduleTrigger record);
/**
* 获取所有的定时调度任务信息t_schedule_trigger
*/
List<ScheduleTtrigger> queryScheduleTtrigger();
}

ScheduleTtriggerMapper.xml

  <select id="queryScheduleTtrigger" resultType="com.jt.quartz02.model.ScheduleTtrigger">
SELECT
<include refid="Base_Column_List"/>
FROM t_schedule_trigger
</select>

ScheduleTriggerParamMapper

package com.jt.quartz02.mapper;

import com.jt.quartz02.model.ScheduleTriggerParam;
import org.springframework.stereotype.Repository; import java.util.List; @Repository
public interface ScheduleTriggerParamMapper {
int deleteByPrimaryKey(Integer param_id); int insert(ScheduleTriggerParam record); int insertSelective(ScheduleTriggerParam record); ScheduleTriggerParam selectByPrimaryKey(Integer param_id); int updateByPrimaryKeySelective(ScheduleTriggerParam record); int updateByPrimaryKey(ScheduleTriggerParam record); /**
* 根据定时任务id获取任务对应的执行参数信息
*/
List<ScheduleTriggerParam> queryScheduleParams(Integer id);
}

ScheduleTriggerParamMapper.xml

    <select id="queryScheduleParams" resultType="com.jt.quartz02.model.ScheduleTriggerParam">
SELECT
<include refid="Base_Column_List"/>
FROM t_schedule_trigger_param where
schedule_trigger_id=#{id}
</select>

spring自带定时任务作业类SScheduleTriggerParamServiceImpl

package com.jt.quartz02.service.impl;

import com.jt.quartz02.mapper.ScheduleTriggerParamMapper;
import com.jt.quartz02.mapper.ScheduleTtriggerMapper;
import com.jt.quartz02.model.ScheduleTriggerParam;
import com.jt.quartz02.model.ScheduleTtrigger;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import java.util.List; @Service
public class SScheduleTriggerParamServiceImpl { //获取调度器实例
@Autowired
private Scheduler scheduler; @Autowired
private ScheduleTtriggerMapper sheduleTtriggerMapper; @Autowired
private ScheduleTriggerParamMapper scheduleTriggerParamMapper; @Scheduled(cron = "*/10 * * * * ?")
public void reflushScheduler(){
try {
//1.循环获取数据库里面的所有定时任务信息
List<ScheduleTtrigger> list = sheduleTtriggerMapper.queryScheduleTtrigger();
//2.循环遍历
for (ScheduleTtrigger scheduleTtrigger : list) {
//获取cron表达式
String cron=scheduleTtrigger.getCron();
//获取Jobname,job任务类的全路径名
String jobname=scheduleTtrigger.getJobName();
//获取JobGroup
String jobGroup=scheduleTtrigger.getJobGroup();
//获取Status运行状态
String status=scheduleTtrigger.getStatus();
//3.根据Jobname和JobGroup生成TriggerKey
TriggerKey triggerKey = TriggerKey.triggerKey(jobname, jobGroup);
//4根据TriggerKey获取Scheduler调度器中的触发器,并判断是否为null,不为null即存在
CronTrigger trigger =(CronTrigger) scheduler.getTrigger(triggerKey);
//5判断是否为null
if(null==trigger){
//6.判断当前kob任务是否可用
if(status.equals(""))
continue;
//7.创建JobDetail
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobname))
.withIdentity(jobname,jobGroup)
.build();
//8.传递参数到job任中
JobDataMap jobDataMap=jobDetail.getJobDataMap();
//获取调度器任务id
Integer scheduleid=scheduleTtrigger.getId();
List<ScheduleTriggerParam> params = scheduleTriggerParamMapper.queryScheduleParams(scheduleid);
for (ScheduleTriggerParam param : params) {
jobDataMap.put(param.getName(),param.getValue());
}
//9.创建cron表达式调度器
CronScheduleBuilder cronScheduleBuilder =
CronScheduleBuilder.cronSchedule(cron);
//10 创建cron表达式触发器
trigger=TriggerBuilder.newTrigger()
.withIdentity(jobname,jobGroup)
.withSchedule(cronScheduleBuilder)
.build();
//11.将jobDetail和Trigger注入到调度器中
scheduler.scheduleJob(jobDetail,trigger);
} else{
System.out.println("Quartz调度器实例已经存在");
if(status.equals("")){
//删除调度任务
JobKey jobKey=JobKey.jobKey(jobname,jobGroup);
scheduler.deleteJob(jobKey);
continue;
} //获取调度器中的表达式
String cronExpression = trigger.getCronExpression();
//将调度器中的cron与数据库中的job任务进行比对
if(!cron.equals(cronExpression)){
//重构表达式调度器
CronScheduleBuilder newCronSchedule = CronScheduleBuilder.cronSchedule(cron);
//重构CronTrigger
trigger=TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.withSchedule(newCronSchedule)
.build();
//刷新调度器实例
scheduler.rescheduleJob(triggerKey,trigger); }
}
}
} catch (Exception e) {
e.printStackTrace();
} } }

MyJob.java

package com.jt.quartz02.quartz;

import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component; import java.util.Date; @Component
@Slf4j
public class MyJob implements Job{ //获取spring 上下文的Bean
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("这是一个简单的Job任务调度实例"+ new Date().toLocaleString());
} }

Spring自带定时任务每10s执行一次,查询自定义触发器表,获取到具体的作业类及任务表达式,quartz的任务为每5s执行一次,所以打印如上

MyJob1.java

package com.jt.quartz02.quartz;

import com.jt.quartz02.model.ScheduleTriggerParam;
import com.jt.quartz02.service.IScheduleTriggerParamService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.util.Date;
import java.util.List; @Component
@Slf4j
public class MyJob1 implements Job{ @Autowired
private IScheduleTriggerParamService IScheduleTriggerParamService;
//获取spring 上下文的Bean
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("这是一个获取sprig中Bean的job任务"+new Date().toLocaleString()); List<ScheduleTriggerParam> scheduleTriggerParams =
IScheduleTriggerParamService.queryScheduleParams();
System.out.println("参数数量"+scheduleTriggerParams.size());
} }

MyJob2.java

package com.jt.quartz02.quartz;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Component; import java.util.Date;
@Component
@Slf4j
public class MyJob2 implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDetail jobDetail =
jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
System.out.println(new Date().toLocaleString()+"-->MyJob2参数传递name="+jobDataMap.get("name")+",score="+
jobDataMap.get("score"));
}

springboot+quartz+数据库存储的更多相关文章

  1. spring boot+Quartz+数据库存储

    SpingBoot+Quartz+数据库存储 1.Spring整合Quartz 2.读取数据库中表达式启动定时任务1(每5s执行) 3.更改定时任务状态(启用/禁用),定时任务1停止 4.读取数据库中 ...

  2. SpringBoot + Quartz定时任务示例

    程序文件结构,如下图,后面详细列出各文件的代码: 1. maven的pom.xml文件如下: <project xmlns="http://maven.apache.org/POM/4 ...

  3. springBoot+springSecurity 数据库动态管理用户、角色、权限

    使用spring Security3的四种方法概述 那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中,已经实现过, ...

  4. 使用quartz数据库锁实现定时任务的分布式部署

    ,1.根据项目引用的quartz依赖版本,确定下载的quartz-distribution安装包,我项目引用的信息如下图所示: 2.解压,在\quartz-2.2.3-distribution\qua ...

  5. spring-boot+quartz的CRUD动态任务管理系统

    版权声明:作者: 小柒 出处: https://blog.52itstyle.com 分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大 ...

  6. quartz定时任务存储

    今天不聊quartz的概念,像任务bean,触发器,调度器这些随随便便都可以百度到,其中任务bean要实现job接口.对于这些创建生成的定时任务,它可以保存在内存中,重启失效,也可以保存在数据库里重启 ...

  7. springBoot+springSecurity 数据库动态管理用户、角色、权限(二)

    序: 本文使用springboot+mybatis+SpringSecurity 实现数据库动态的管理用户.角色.权限管理 本文细分角色和权限,并将用户.角色.权限和资源均采用数据库存储,并且自定义滤 ...

  8. mysql数据库存储路径更改 数据文件位置

    使用了VPS一段时间之后发现磁盘空间快满了.本人的VPS在购买的时候买了500gb的磁盘,提供商赠送了20GB的高性能系统磁盘.这样系统就有两个磁盘空间了.在初次安装mysql 的时候将数据库目录安装 ...

  9. DDD开发框架ABP之本地化资源的数据库存储扩展

    在上一篇<DDD开发框架ABP之本地化/多语言支持>中,我们知道,ABP开发框架中本地化资源存储可以采用XML文件,RESX资源文件,也提供了其他自定义的存储方式的扩展接口.ABP框架默认 ...

随机推荐

  1. HDU2482-Transit search(地图还原+SPFA)

    Henry decides to develop a web site, which will provide the service of transit search. But he can on ...

  2. Selenium之编辑框操作

    编辑框操作: 网页上随处可见的编辑框,有时候编辑框里有默认的提示文字或者当我们需要输入第二次测试数据时,须先用clear()方法清除该元素里的字符串,再输入文本: 那么如何获取输入框已经输入的文本内容 ...

  3. 使用java语言实现八皇后问题

    八皇后问题,在一个8X8的棋盘中,放置八个棋子,每个棋子的上下左右,左上左下,右上右下方向上不得有其他棋子.正确答案为92中,接下来用java语言实现. 解: package eightQuen; / ...

  4. Git下载安装及github基本操作

    Windows下Git下载 官网提供的Git下载地址: 官网下载地址,一般直接从官网下载会出现无反应等情况,这里提供windows32和64位版本的百度网盘资源:windows下的Git下载地址.有需 ...

  5. 【系列专题】ECMAScript 重温系列(10篇全)

    ES6 系列ECMAScript 2015 [ES]150-重温基础:ES6系列(一) [ES]151-重温基础:ES6系列(二) [ES]152-重温基础:ES6系列(三) [ES]153-重温基础 ...

  6. 细解JavaScript ES7 ES8 ES9 新特性

    题记:本文提供了一个在线PPT版本,方便您浏览 细解JAVASCRIPT ES7 ES8 ES9 新特性 在线PPT ver 本文的大部分内容译自作者Axel Rauschmayer博士的网站,想了解 ...

  7. ASP.NET Core开发者指南()

    你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“作为 ASP.NET Core 开发者,我接下来应该学习什么?”,我把这张图作为建议 ...

  8. CSRF与auth模块

    目录 一.模拟实现中间件的编程思想 (一)impotlib模块 (二)实现功能的配置使用 二.跨站请求伪造CSRF (一)由来 (二)form表单的CSRF (三)ajax中的CSRF (1)通过da ...

  9. IPFS学习-哈希

    Hashes 哈希函数是接受一些任意输入并返回固定长度值的函数.具体值取决于所使用的给定哈希算法,例如SHA-1(GIT在使用),SHA-256,或者是BLAKE2,但是给予一个输入使用哈希算法总是返 ...

  10. Redis 底层数据结构介绍

    Redis 底层数据结构 版本:2.9 支持的数据类型: 字符串 散列 列表 集合 有序集合 字符串 Redis 利用原生的 c 字符串进行了一次封装.封装的字符串叫做简单动态字符串:SDS(simp ...