当前位置:Gxlcms > 数据库问题 > SpringBoot+Quartz+数据库存储

SpringBoot+Quartz+数据库存储

时间:2021-07-01 10:21:17 帮助过:17人阅读

Quartz

quartz调度框架是有内置表的,进入quartz的官网http://www.quartz-scheduler.org/,点击Downloads下载后在目录\docs\dbTables下有常用数据库创建quartz表的脚本,例如:“tables_mysql.sql

技术图片

 

技术图片

导入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.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.javaqi</groupId>
<artifactId>quartz02</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quartz02</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<mysql.version>5.1.44</mysql.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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.1</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>

<build>
<resources>
<resource><directory>src/main/resources</directory></resource>
<!--解决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.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>${mysql.version}</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
 

 

在项目中添加quartz.properties文件(这样就不会加载自带的properties文件)

此文件的内容主要分为:schedulerThreadPoolJobStorepluginDatasources等部分,

覆盖properties文件的目的是覆盖默认的数据源,更换为druid的数据配置

quartz.properties

 1 #
 2 #============================================================================
 3 # Configure Main Scheduler Properties 调度器属性
 4 #============================================================================
 5 org.quartz.scheduler.instanceName: DefaultQuartzScheduler
 6 org.quartz.scheduler.instanceId = AUTO
 7 org.quartz.scheduler.rmi.export: false
 8 org.quartz.scheduler.rmi.proxy: false
 9 org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
10 org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
11 org.quartz.threadPool.threadCount= 10
12 org.quartz.threadPool.threadPriority: 5
13 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
14 org.quartz.jobStore.misfireThreshold: 60000
15 #============================================================================
16 # Configure JobStore
17 #============================================================================
18 #存储方式使用JobStoreTX,也就是数据库
19 org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
20 org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
21 #使用自己的配置文件
22 org.quartz.jobStore.useProperties:true
23 #数据库中quartz表的表名前缀
24 org.quartz.jobStore.tablePrefix:qrtz_
25 org.quartz.jobStore.dataSource:qzDS
26 #是否使用集群(如果项目只部署到 一台服务器,就不用了)
27 org.quartz.jobStore.isClustered = true
28 #============================================================================
29 # Configure Datasources
30 #============================================================================
31 #配置数据库源(org.quartz.dataSource.qzDS.maxConnections: c3p0配置的是有s的,druid数据源没有s)
32 org.quartz.dataSource.qzDS.connectionProvider.class:com.javaqi.quartz02.utils.DruidConnectionProvider
33 org.quartz.dataSource.qzDS.driver: com.mysql.jdbc.Driver
34 org.quartz.dataSource.qzDS.URL: jdbc:mysql://localhost:3306/xufanqi?useUnicode=true&characterEncoding=utf8
35 org.quartz.dataSource.qzDS.user: root
36 org.quartz.dataSource.qzDS.password: 123
37 org.quartz.dataSource.qzDS.maxConnection: 10

自定义MyJobFactory,解决spring不能在quartz中注入bean的问题

MyJobFactory 
 1 package com.javaqi.quartz02.utils;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.quartz.spi.TriggerFiredBundle;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 7 import org.springframework.scheduling.quartz.AdaptableJobFactory;
 8 import org.springframework.stereotype.Component;
 9 
10 @Component
11 @Slf4j
12 public class MyJobFactory extends AdaptableJobFactory {
13 
14     //这个对象Spring会帮我们自动注入进来
15     @Autowired
16     private AutowireCapableBeanFactory autowireCapableBeanFactory;
17 
18     //重写创建Job任务的实例方法
19     @Override
20     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
21         Object jobInstance = super.createJobInstance(bundle);
22         //通过以下方式,解决Job任务无法使用Spring中的Bean问题
23         autowireCapableBeanFactory.autowireBean(jobInstance);
24         return super.createJobInstance(bundle);
25     }
26 }

从数据库读取任务信息动态生成定时任务,和把quartz持久化到数据库是没有关系的。前者是我们自己定义的业务表,而后者是quartz使用自己的表来存储信息。持久化到数据库后,就算服务器重启或是多个quartz节点也没关系,因为他们共享数据库中的任务信息。

DruidConnectionProvider.java

  1 package com.javaqi.quartz02.utils;
  2 
  3 import com.alibaba.druid.pool.DruidDataSource;
  4 import org.quartz.SchedulerException;
  5 import org.quartz.utils.ConnectionProvider;
  6 
  7 import java.sql.Connection;
  8 import java.sql.SQLException;
  9 
 10 /*
 11 #============================================================================
 12 # JDBC
 13 #============================================================================
 14 org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 15 org.quartz.jobStore.useProperties:false
 16 org.quartz.jobStore.dataSource:qzDS
 17 #org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider
 18 org.quartz.dataSource.qzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProvider
 19 org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
 20 org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
 21 org.quartz.dataSource.qzDS.user:root
 22 org.quartz.dataSource.qzDS.password:root
 23 org.quartz.dataSource.qzDS.maxConnections:30
 24 org.quartz.dataSource.qzDS.validationQuery: select 0
 25 */
 26 
 27 /**
 28  * [Druid连接池的Quartz扩展类]
 29  *
 30  * @ProjectName: []
 31  * @Author: [xuguang]
 32  * @CreateDate: [2015/11/10 17:58]
 33  * @Update: [说明本次修改内容] BY[xuguang][2015/11/10]
 34  * @Version: [v1.0]
 35  */
 36 public class DruidConnectionProvider implements ConnectionProvider {
 37 
 38      /*
 39      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 40      *
 41      * 常量配置,与quartz.properties文件的key保持一致(去掉前缀),同时提供set方法,Quartz框架自动注入值。
 42      *
 43      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 44      */
 45 
 46     //JDBC驱动
 47     public String driver;
 48     //JDBC连接串
 49     public String URL;
 50     //数据库用户名
 51     public String user;
 52     //数据库用户密码
 53     public String password;
 54     //数据库最大连接数
 55     public int maxConnection;
 56     //数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。
 57     public String validationQuery;
 58 
 59     private boolean validateOnCheckout;
 60 
 61     private int idleConnectionValidationSeconds;
 62 
 63     public String maxCachedStatementsPerConnection;
 64 
 65     private String discardIdleConnectionsSeconds;
 66 
 67     public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;
 68 
 69     public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;
 70 
 71     //Druid连接池
 72     private DruidDataSource datasource;
 73 
 74     /*
 75     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 76     *
 77     * 接口实现
 78     *
 79     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 80     */
 81     public Connection getConnection() throws SQLException {
 82         return datasource.getConnection();
 83     }
 84 
 85     public void shutdown() throws SQLException {
 86         datasource.close();
 87     }
 88     public void initialize() throws SQLException{
 89         if (this.URL == null) {
 90             throw new SQLException("DBPool could not be created: DB URL cannot be null");
 91         }
 92 
 93         if (this.driver == null) {
 94             throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");
 95         }
 96 
 97         if (this.maxConnection < 0) {
 98             throw new SQLException("DBPool maxConnectins could not be created: Max connections must be greater than zero!");
 99         }
100 
101         datasource = new DruidDataSource();
102         try{
103             datasource.setDriverClassName(this.driver);
104         } catch (Exception e) {
105             try {
106                 throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);
107             } catch (SchedulerException e1) {
108             }
109         }
110 
111         datasource.setUrl(this.URL);
112         datasource.setUsername(this.user);
113         datasource.setPassword(this.password);
114         datasource.setMaxActive(this.maxConnection);
115         datasource.setMinIdle(1);
116         datasource.setMaxWait(0);
117         datasource.setMaxPoolPreparedStatementPerConnectionSize(this.DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION);
118 
119         if (this.validationQuery != null) {
120             datasource.setValidationQuery(this.validationQuery);
121             if(!this.validateOnCheckout)
122                 datasource.setTestOnReturn(true);
123             else
124                 datasource.setTestOnBorrow(true);
125             datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);
126         }
127     }
128 
129     /*
130     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131     *
132     * 提供get set方法
133     *
134     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135     */
136     public String getDriver() {
137         return driver;
138     }
139 
140     public void setDriver(String driver) {
141         this.driver = driver;
142     }
143 
144     public String getURL() {
145         return URL;
146     }
147 
148     public void setURL(String URL) {
149         this.URL = URL;
150     }
151 
152     public String getUser() {
153         return user;
154     }
155 
156     public void setUser(String user) {
157         this.user = user;
158     }
159 
160     public String getPassword() {
161         return password;
162     }
163 
164     public void setPassword(String password) {
165         this.password = password;
166     }
167 
168     public int getMaxConnection() {
169         return maxConnection;
170     }
171 
172     public void setMaxConnection(int maxConnection) {
173         this.maxConnection = maxConnection;
174     }
175 
176     public String getValidationQuery() {
177         return validationQuery;
178     }
179 
180     public void setValidationQuery(String validationQuery) {
181         this.validationQuery = validationQuery;
182     }
183 
184     public boolean isValidateOnCheckout() {
185         return validateOnCheckout;
186     }
187 
188     public void setValidateOnCheckout(boolean validateOnCheckout) {
189         this.validateOnCheckout = validateOnCheckout;
190     }
191 
192     public int getIdleConnectionValidationSeconds() {
193         return idleConnectionValidationSeconds;
194     }
195 
196     public void setIdleConnectionValidationSeconds(int idleConnectionValidationSeconds) {
197         this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;
198     }
199 
200     public DruidDataSource getDatasource() {
201         return datasource;
202     }
203 
204     public void setDatasource(DruidDataSource datasource) {
205         this.datasource = datasource;
206     }
207 }
QuartzConfiguration.javaquartz调度框架与spring框架整合的配置类,主要是要将org.quartz.Scheduler交给spring进行管理)
QuartzConfiguration
 1 package com.javaqi.quartz02.config;
 2 
 3 import com.javaqi.quartz02.utils.MyJobFactory;
 4 import org.quartz.Scheduler;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.beans.factory.config.PropertiesFactoryBean;
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.context.annotation.Configuration;
 9 import org.springframework.core.io.ClassPathResource;
10 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
11 
12 import java.io.IOException;
13 import java.util.Properties;
14 
15 @Configuration
16 public class QuartzConfiguration {
17 
18     @Autowired
19     private MyJobFactory myJobFactory;
20 
21     //创建调度器工厂
22     @Bean
23         public SchedulerFactoryBean schedulerFactoryBean(){
24             //1.创建SchedulerFactoryBean
25             //2.加载自定义的quartz.properties配置文件
26             //3.设置MyJobFactory
27 
28             SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
29             try {
30                 factoryBean.setQuartzProperties(quartzProperties());
31                 factoryBean.setJobFactory(myJobFactory);
32                 return factoryBean;
33             } catch (IOException e) {
34                 throw new RuntimeException(e);
35             }
36     }
37 
38     @Bean
39     public Properties quartzProperties() throws IOException {
40         PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean();
41         propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
42         propertiesFactoryBean.afterPropertiesSet();
43         return propertiesFactoryBean.getObject();
44     }
45 
46     @Bean(name="scheduler")
47     public Scheduler scheduler(){
48         return schedulerFactoryBean().getScheduler();
49     }
50 }

配置application.yml

 1 server:
 2   servlet:
 3     context-path: /
 4   port: 80
 5 spring:
 6   datasource:
 7     #1.JDBC
 8     type: com.alibaba.druid.pool.DruidDataSource
 9     driver-class-name: com.mysql.jdbc.Driver
10     url: jdbc:mysql://localhost:3306/xufanqi?useUnicode=true&characterEncoding=utf8
11     username: root
12     password: 123
13     druid:
14       #2.\u8FDE\u63A5\u6C60\u914D\u7F6E
15       #\u521D\u59CB\u5316\u8FDE\u63A5\u6C60\u7684\u8FDE\u63A5\u6570\u91CF \u5927\u5C0F\uFF0C\u6700\u5C0F\uFF0C\u6700\u5927
16       initial-size: 5
17       min-idle: 5
18       max-active: 20
19       #\u914D\u7F6E\u83B7\u53D6\u8FDE\u63A5\u7B49\u5F85\u8D85\u65F6\u7684\u65F6\u95F4
20       max-wait: 60000
21       #\u914D\u7F6E\u95F4\u9694\u591A\u4E45\u624D\u8FDB\u884C\u4E00\u6B21\u68C0\u6D4B\uFF0C\u68C0\u6D4B\u9700\u8981\u5173\u95ED\u7684\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
22       time-between-eviction-runs-millis: 60000
23       # \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5C0F\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
24       min-evictable-idle-time-millis: 30000
25       validation-query: SELECT 1 FROM DUAL
26       test-while-idle: true
27       test-on-borrow: true
28       test-on-return: false
29       # \u662F\u5426\u7F13\u5B58preparedStatement\uFF0C\u4E5F\u5C31\u662FPSCache  \u5B98\u65B9\u5EFA\u8BAEMySQL\u4E0B\u5EFA\u8BAE\u5173\u95ED   \u4E2A\u4EBA\u5EFA\u8BAE\u5982\u679C\u60F3\u7528SQL\u9632\u706B\u5899 \u5EFA\u8BAE\u6253\u5F00
30       pool-prepared-statements: true
31       max-pool-prepared-statement-per-connection-size: 20
32       # \u914D\u7F6E\u76D1\u63A7\u7EDF\u8BA1\u62E6\u622A\u7684filters\uFF0C\u53BB\u6389\u540E\u76D1\u63A7\u754C\u9762sql\u65E0\u6CD5\u7EDF\u8BA1\uFF0C‘wall‘\u7528\u4E8E\u9632\u706B\u5899
33       filter:
34         stat:
35           merge-sql: true
36           slow-sql-millis: 5000
37       #3.\u57FA\u7840\u76D1\u63A7\u914D\u7F6E
38       web-stat-filter:
39         enabled: true
40         url-pattern: /*
41         #\u8BBE\u7F6E\u4E0D\u7EDF\u8BA1\u54EA\u4E9BURL
42         exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
43         session-stat-enable: true
44         session-stat-max-count: 100
45       stat-view-servlet:
46         enabled: true
47         url-pattern: /druid/*
48         reset-enable: true
49         #\u8BBE\u7F6E\u76D1\u63A7\u9875\u9762\u7684\u767B\u5F55\u540D\u548C\u5BC6\u7801
50         login-username: admin
51         login-password: admin
52         allow: 127.0.0.1
53         #deny: 192.168.1.100
54 
55 #\u663E\u793A\u65E5\u5FD7
56 logging:
57   level:
58     com.javaqi.quartz02.mapper: debug

Quartz02Application.java

 1 package com.javaqi.quartz02;
 2 
 3 import org.mybatis.spring.annotation.MapperScan;
 4 import org.springframework.boot.SpringApplication;
 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
 6 import org.springframework.scheduling.annotation.EnableScheduling;
 7 import org.springframework.transaction.annotation.EnableTransactionManagement;
 8 
 9 @MapperScan("com.javaqi.quartz02.mapper")
10 @EnableTransactionManagement
11 @EnableScheduling
12 @SpringBootApplication
13 public class Quartz02Application {
14 
15     public static void main(String[] args) {
16         SpringApplication.run(Quartz02Application.class, args);
17     }
18 
19 }

逆向生成

generatorConfig.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
 3         "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
 4 <generatorConfiguration>
 5     <!-- 引入配置文件 -->
 6     <properties resource="jdbc.properties"/>
 7 
 8     <!--指定数据库jdbc驱动jar包的位置-->
 9     <classPathEntry location="D:\apache-maven-3.5.0-bin\apache-maven-3.5.0-bin\Mvn_repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
10 
11     <!-- 一个数据库一个context -->
12     <context id="infoGuardian">
13         <!-- 注释 -->
14         <commentGenerator>
15             <property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
16             <property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
17         </commentGenerator>
18 
19         <!-- jdbc连接 -->
20         <jdbcConnection driverClass="${jdbc.driver}"
21                         connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
22 
23         <!-- 类型转换 -->
24         <javaTypeResolver>
25             <!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
26             <property name="forceBigDecimals" value="false"/>
27         </javaTypeResolver>
28 
29         <!-- 01 指定javaBean生成的位置 -->
30         <!-- targetPackage:指定生成的model生成所在的包名 -->
31         <!-- targetProject:指定在该项目下所在的路径  -->
32         <javaModelGenerator targetPackage="com.javaqi.quartz02.model"
33                             targetProject="src/m                    

人气教程排行