千家信息网

如何集合SpringBoot+Quartz+数据库存储

发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,这篇文章主要介绍如何集合SpringBoot+Quartz+数据库存储,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!官网:http://www.quartz-scheduler
千家信息网最后更新 2025年11月16日如何集合SpringBoot+Quartz+数据库存储

这篇文章主要介绍如何集合SpringBoot+Quartz+数据库存储,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

官网:http://www.quartz-scheduler.org/

我们所需数据库

pom依赖

   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                        

Quartz默认的连接池是c3p0,如果你的连接池不同需要直接替换它的配置文件,比如我用的连接池是druid,就需要自己改配置(如果就用c3p0就不需要改) 工具类 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干的漂亮 * @site www.wangmage.com * @company 干得漂亮公司 * @create 2019 - 11-15 17:05 */@Component@Slf4jpublic class MyJobFactory extends AdaptableJobFactory {    //这个对象Spring会帮我们自动注入进来    @Autowired    private AutowireCapableBeanFactory autowireCapableBeanFactory;    //重写创建Job任务的实例方法    @Override    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {        Object jobInstance = super.createJobInstance(bundle);        //通过以下方式,解决Job任务无法使用Spring中的Bean问题        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 0*//** * @author干的漂亮 * @site www.wangmage.com * @company 干得漂亮公司 * @create 2019 - 11-15 17:02 *//** * [Druid连接池的Quartz扩展类] * * @ProjectName: [] * @Author: [xuguang] * @CreateDate: [2015/11/10 17:58] * @Update: [说明本次修改内容] BY[xuguang][2015/11/10] * @Version: [v1.0] */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 = 10;    public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;    //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 < 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

ScheduleTrigger

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()+"-->携带参数个数:"+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参数传递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干的漂亮 * @site www.wangmage.com * @company 干得漂亮公司 * @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干的漂亮 * @site www.wangmage.com * @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);        /**         * 查询触发器中包含的所有任务         * @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);    }}

界面

        quartz定时任务管理

定时任务

id 表达式 状态 工作类 分组 操作
启动 停止 编辑 增加

edit.html

        修改定时任务

修改定时任务

表达式:
工作类:
分组:

以上是"如何集合SpringBoot+Quartz+数据库存储"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

0