How to assemble SpringBoot+Quartz+ database storage
This article mainly introduces how to set SpringBoot+Quartz+ database storage, the article is very detailed, has a certain reference value, interested friends must read it!
Official website: http://www.quartz-scheduler.org/
The database we need
Pom dependence
Spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-quartz org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot Mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java ${mysql.version} runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test Test org.junit.vintage junit-vintage-engine org.quartz-scheduler quartz-jobs 2.2.1 com.alibaba druid- Spring-boot-starter 1.1.10 src/main/resources src/main/java * * / * .xml Src/main/resources * .properties * .xml * .yml org.mybatis.generator mybatis-generator-maven-plugin 1.3.2 mysql mysql-connector-java ${mysql.version} true Org.springframework.boot spring-boot-maven-plugin
The default connection pool for Quartz is c3p0. If your connection pool is different, you need to replace its configuration file directly. For example, if the connection pool I use is druid, you need to change the configuration yourself (if you use c3p0, you don't need to change it) tool class utils MyJobFactory
Package com.wsy.quartz02.utils;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 / * * @ author Nice work * @ site www.wangmage.com * @ company Nice work Company * @ create 2019-11-15 17:05 * / @ Component@Slf4jpublic class MyJobFactory extends AdaptableJobFactory {/ / this object Spring will help us automatically inject @ Autowired private AutowireCapableBeanFactory autowireCapableBeanFactory; / / rewrite the instance method @ Override protected Object createJobInstance (TriggerFiredBundle bundle) throws Exception {Object jobInstance = super.createJobInstance (bundle) to create the Job task. / / resolve the problem that Job tasks cannot use Bean in Spring in the following ways: autowireCapableBeanFactory.autowireBean (jobInstance); return super.createJobInstance (bundle);}}
DruidConnectionProvider
Package com.wsy.quartz02.utils;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.StdJDBCDelegateorg.quartz.jobStore.useProperties:falseorg.quartz.jobStore.dataSource:qzDS#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProviderorg.quartz.dataSource.qzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProviderorg.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driverorg.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306 / test?useUnicode=true&characterEncoding=UTF-8org.quartz.dataSource.qzDS.user:rootorg.quartz.dataSource.qzDS.password:rootorg.quartz.dataSource.qzDS.maxConnections:30org.quartz.dataSource.qzDS.validationQuery: select 0hammer pool * * @ author Nice work * @ site www.wangmage.com * @ company Nice work * @ create 2019-11-15 17:02 * / / * * [Quartz extension to Druid connection pool] * * ProjectName: [] * @ Author: [xuguang] * @ CreateDate: [17:58 on 2015-11-10] * @ Update: [explain this modification] BY [xuguang] [2015-11-10] * @ Version: [v1.0] * / public class DruidConnectionProvider implements ConnectionProvider {/ * ~ ~ * * constant configuration Consistent with the key of the quartz.properties file (remove the prefix), while providing the set method, the Quartz framework automatically injects values. * * ~ ~ * / / JDBC driver public String driver; / / JDBC connection string public String URL; / / Database user name public String user; / / Database user password public String password; / / maximum number of database connections public int maxConnection; / / Database SQL query returns each connection to the connection pool to ensure that it is still valid. Public String validationQuery; private boolean validateOnCheckout; private int idleConnectionValidationSeconds; public String maxCachedStatementsPerConnection; private String discardIdleConnectionsSeconds; public static final int DEFAULT_DB_MAX_CONNECTIONS = 10; public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120; / / Druid connection pool private DruidDataSource datasource / * * API implementation * * ~ ~ * / 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)
< 0) { 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(1); datasource.setMaxWait(0); 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; }} application.yml server: servlet: context-path: / port: 80spring: datasource: #1.JDBC type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8 username: root password: 123 druid: #2.连接池配置 #初始化连接池的连接数量 大小,最小,最大 initial-size: 5 min-idle: 5 max-active: 20 #配置获取连接等待超时的时间 max-wait: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 30000 validation-query: SELECT 1 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: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filter: stat: merge-sql: true slow-sql-millis: 5000 #3.基础监控配置 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 #deny: 192.168.1.100#显示日志logging: level: com.wsy.quartz02.mapper: debug quartz.properties ##============================================================================# Configure Main Scheduler Properties 调度器属性#============================================================================org.quartz.scheduler.instanceName: DefaultQuartzSchedulerorg.quartz.scheduler.instanceId = AUTOorg.quartz.scheduler.rmi.export: falseorg.quartz.scheduler.rmi.proxy: falseorg.quartz.scheduler.wrapJobExecutionInUserTransaction: falseorg.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount= 10org.quartz.threadPool.threadPriority: 5org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: trueorg.quartz.jobStore.misfireThreshold: 60000#============================================================================# Configure JobStore#============================================================================#存储方式使用JobStoreTX,也就是数据库org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate#使用自己的配置文件org.quartz.jobStore.useProperties:true#数据库中quartz表的表名前缀org.quartz.jobStore.tablePrefix:qrtz_org.quartz.jobStore.dataSource:qzDS#是否使用集群(如果项目只部署到 一台服务器,就不用了)org.quartz.jobStore.isClustered = true#============================================================================# Configure Datasources#============================================================================#配置数据库源(org.quartz.dataSource.qzDS.maxConnections: c3p0配置的是有s的,druid数据源没有s)org.quartz.dataSource.qzDS.connectionProvider.class:com.wsy.quartz02.utils.DruidConnectionProviderorg.quartz.dataSource.qzDS.driver: com.mysql.jdbc.Driverorg.quartz.dataSource.qzDS.URL: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8org.quartz.dataSource.qzDS.user: rootorg.quartz.dataSource.qzDS.password: 123org.quartz.dataSource.qzDS.maxConnection: 10 ScheduleTriggerMapper package com.wsy.quartz02.mapper;import com.wsy.quartz02.model.ScheduleTrigger;import org.springframework.stereotype.Repository;import java.util.List;@Repositorypublic interface ScheduleTriggerMapper { int deleteByPrimaryKey(Integer id); int insert(ScheduleTrigger record); int insertSelective(ScheduleTrigger record); ScheduleTrigger selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(ScheduleTrigger record); int updateByPrimaryKey(ScheduleTrigger record); /** * 查询触发器中包含的所有任务 * @return */ List queryScheduleTriggerLst();} ScheduleTriggerParamMapper package com.wsy.quartz02.mapper;import com.wsy.quartz02.model.ScheduleTriggerParam;import org.springframework.stereotype.Repository;import java.util.List;@Repositorypublic 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); /** * 查询出当前任务类对应所需的参数 * @param triggerId * @return */ List queryScheduleParamLst(Integer triggerId);} ScheduleTriggerParam select from t_schedule_trigger_param where schedule_trigger_id=#{triggerId} ScheduleTrigger select from t_schedule_trigger QuartzConfiguration package com.wsy.config;import com.wsy.quartz02.utils.MyJobFactory;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;@Configurationpublic class QuartzConfiguration { @Autowired private MyJobFactory myJobFactory; //创建调度器工厂 @Bean public SchedulerFactoryBean schedulerFactoryBean(){ //1.创建SchedulerFactoryBean //2.加载自定义的quartz.properties配置文件 //3.设置MyJobFactory SchedulerFactoryBean factoryBean=new SchedulerFactoryBean(); try { factoryBean.setQuartzProperties(quartzProperties()); factoryBean.setJobFactory(myJobFactory); return factoryBean; } catch (IOException e) { throw new RuntimeException(e); } } public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); @Bean(name="scheduler") public Scheduler scheduler(){ return schedulerFactoryBean().getScheduler();} MyJob package com.wsy.quartz02.job;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@Slf4jpublic class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.err.println("MyJob是一个空的任务计划,时间:"+new Date().toLocaleString()); }} MyJob1 package com.wsy.quartz02.job;import lombok.extern.slf4j.Slf4j;import org.quartz.*;import org.springframework.stereotype.Component;import java.util.Date;@Component@Slf4jpublic class MyJob1 implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobDetail jobDetail = jobExecutionContext.getJobDetail(); JobDataMap jobDataMap = jobDetail.getJobDataMap(); System.out.println(new Date().toLocaleString()+"-->Number of parameters carried: "+ jobDataMap.size ();}}"
MyJob2
Package com.wsy.quartz02.job;import lombok.extern.slf4j.Slf4j;import org.quartz.*;import org.springframework.stereotype.Component;import java.util.Date;@Component@Slf4jpublic 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 parameter passing name=" + jobDataMap.get ("name") + ", score=" + jobDataMap.get ("score"));}}
Quartz02Controller
Package com.wsy.quartz02.controler;import com.wsy.quartz02.model.ScheduleTrigger;import com.wsy.quartz02.service.ScheduleTriggerService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import java.util.List / * * @ author well done * @ site www.wangmage.com * @ company well done * @ create 2019-11-16 16:02 * / @ Controller@RequestMapping ("/ quartz") public class Quartz02Controller {@ Autowired private ScheduleTriggerService scheduleTriggerService; @ RequestMapping ("/ list") public ModelAndView getAll () {ModelAndView mv = new ModelAndView (); List list = scheduleTriggerService.queryScheduleTriggerLst (); mv.addObject ("quartzList", list) Mv.setViewName ("index"); return mv;} @ RequestMapping ("/ edit") public String editStatus (ScheduleTrigger scheduleTrigger) {int n = scheduleTriggerService.updateByPrimaryKeySelective (scheduleTrigger); return "redirect:/quartz/list";} @ RequestMapping ("/ proSave/ {id}") public ModelAndView proSave (@ PathVariable (value = "id") Integer id) {ModelAndView mv=new ModelAndView (); ScheduleTrigger scheduleTrigger = scheduleTriggerService.selectByPrimaryKey (id) Mv.addObject ("schedule", scheduleTrigger); mv.setViewName ("edit"); return mv;}}
ScheduleTriggerService
Package com.wsy.quartz02.service;import com.wsy.quartz02.model.ScheduleTrigger;import java.util.List;/** * @ author well done * @ site www.wangmage.com * @ company well done Company * @ create 2019-11-16 16:02 * / public interface ScheduleTriggerService {int deleteByPrimaryKey (Integer id); int insert (ScheduleTrigger record); int insertSelective (ScheduleTrigger record); ScheduleTrigger selectByPrimaryKey (Integer id) Int updateByPrimaryKeySelective (ScheduleTrigger record); int updateByPrimaryKey (ScheduleTrigger record); / * * query all tasks contained in the trigger * @ return * / List queryScheduleTriggerLst ();}
Quartz02Application
Package com.wsy.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;@MapperScan ("com.wsy.quartz02.mapper") @ EnableTransactionManagement@EnableScheduling@SpringBootApplicationpublic class Quartz02Application {public static void main (String [] args) {SpringApplication.run (Quartz02Application.class, args);}}
Interface
Quartz scheduled task management scheduled task id expression status work class grouping operation start stop editing added
Edit.html
Modify scheduled task modify scheduled task expression: work class: grouping:
The above is all the contents of the article "how to collect SpringBoot+Quartz+ database storage". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!