java整合Quartz定时任务(数据库动态存储Job)

如有不对的地方请谅解 么么哒~~~ 可以参考一下我的实现

pom依赖

		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>2.3.2</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.10</version>
		</dependency>

创建数据库表 表名QRTZ_quartz_job

在这里插入图片描述

application.yml配置

quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: always
      comment-prefix: '--'
      table-prefix: QRTZ_
      cluster-checkin-interval: 20000
      job-store:
        class: org.quartz.impl.jdbcjobstore.JobStoreTX
        driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
        useProperties: false
        misfireThreshold: 60000
        isClustered: false
        tablePrefix: QRTZ_
        dataSource: quartzDataSource
      properties:
        org:
          quartz:
            scheduler:
              instanceName: MyScheduler
              instanceId: AUTO
            threadPool:
              class: org.quartz.simpl.SimpleThreadPool
              threadCount: 10
              threadPriority: 5
              threadsInheritContextClassLoaderOfInitializingThread: true
            jobStore:
              class: org.quartz.impl.jdbcjobstore.JobStoreTX
              driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
              useProperties: false
              misfireThreshold: 60000
              isClustered: false
              tablePrefix: QRTZ_
            plugin:
              shutdownhook:
                class: org.quartz.plugins.management.ShutdownHookPlugin
                cleanShutdown: true
        com:
          mchange:
            v2:
              c3p0:
                ComboPooledDataSource:
                  quartzDataSource:
                    driverClass: com.mysql.cj.jdbc.Driver
                    jdbcUrl: jdbc:mysql://IP:端口/库?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
                    user: 账号
                    password: 密码
                    maxPoolSize: 20
                    minPoolSize: 1
                    acquireIncrement: 1
                    maxIdleTime: 60000
                    idleConnectionTestPeriod: 60

写一个bean 在启动项目的时候 查询数据库的job 把cron添加到quartzJob里

这里的 false == CronUtils.isBeforeNow(cronExpression) 是我的工具类等等放在最后

import com.dji.sample.dji.model.entity.QuartzJob;
import com.dji.sample.dji.util.dateformat.CronUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class ActivateJob {

    @Autowired
    private QuartzServiceImpl quartzService;

    //启动定时任务改为运行状态
    @Bean
    public void ActivateJons() throws SchedulerException, ClassNotFoundException {
        //System.out.println("我要恢复!");
        if (quartzService.getJobAll().size() >0){
            List<QuartzJob> allJobs = quartzService.getJobAll();
            for (QuartzJob allJob : allJobs) {
                String cronExpression = allJob.getCronExpression();
                //只执行当前时间之后的飞行任务
                if (false == CronUtils.isBeforeNow(cronExpression)){
                    //添加数据库的job
                    quartzService.addJob(allJob);
                    //恢复job定时任务
//                    quartzService.resumeJob(allJob);
                }
            }
        }
    }


}

实现类 QuartzServiceImpl 因为库很简单 所以用的mybatisplus 继承的baseMapper

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dji.sample.dji.dao.QuartzMapper;
import com.dji.sample.dji.model.entity.QuartzJob;
import com.dji.sample.dji.service.IQuartzService;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QuartzServiceImpl implements IQuartzService {

    @Autowired
    private Scheduler scheduler;
    @Autowired
    private QuartzMapper quartzMapper;

    /**
     * 添加定时任务
     */
    public void addJob(QuartzJob job) throws SchedulerException, ClassNotFoundException {
        // 创建JobDetail实例,绑定Job实现类
        JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getJobClassName()))
                .withIdentity(job.getJobName(), job.getGroupName())
                .build();
        // 设置触发器类型为Cron表达式类型,并绑定Cron表达式规则到触发器上
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(job.getJobName(), job.getGroupName())
                .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
                .build();
        // 将JobDetail和CronTrigger注册到Scheduler中,并启动调度器
        scheduler.scheduleJob(jobDetail, cronTrigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    @Override
    public Integer insert(QuartzJob quartzJob) {
        return quartzMapper.insert(quartzJob);
    }

    @Override
    public QuartzJob getJob(String id) {
        QueryWrapper<QuartzJob> wrapper = new QueryWrapper<QuartzJob>();
        wrapper.eq("job_name",id);
        wrapper.eq("del",0);
        QuartzJob quartzJob = quartzMapper.selectOne(wrapper);
        return quartzJob;
    }

    @Override
    public Integer update(QuartzJob quartzJob) {
        return quartzMapper.updateById(quartzJob);
    }

    /**
     * 修改定时任务的执行时间
     */
    public void modifyJob(QuartzJob job) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getGroupName());
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        if (cronTrigger == null) {
            return;
        }
        String oldCronExpression = cronTrigger.getCronExpression();
        if (!oldCronExpression.equals(job.getCronExpression())) {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            cronTrigger = cronTrigger.getTriggerBuilder()
                    .withIdentity(triggerKey)
                    .withSchedule(scheduleBuilder)
                    .build();
            scheduler.rescheduleJob(triggerKey, cronTrigger);
        }
    }

    /**
     * 删除定时任务
     */
    public void deleteJob(QuartzJob job) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
        scheduler.deleteJob(jobKey);
    }

    /**
     * 暂停定时任务的执行
     */
    public void pauseJob(QuartzJob job) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复定时任务的执行
     */
    public void resumeJob(QuartzJob job) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
        scheduler.resumeJob(jobKey);
    }

    //恢复定时任务
    public void checkJobStatus(QuartzJob job) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null) {
            System.out.println("Job does not exist");
        } else {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            if (triggers != null && triggers.size() > 0) {
                for (Trigger trigger : triggers) {
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    System.out.println("Trigger state: " + triggerState);
                }
            } else {
                System.out.println("No triggers found for the job");
            }
        }
    }

    //查询所有job
    public List<QuartzJob> getJobAll(){
        QueryWrapper<QuartzJob> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("del",0);
        List<QuartzJob> quartzJobs = quartzMapper.selectList(objectQueryWrapper);
        return quartzJobs;
    }

    /**
     * 获取所有定时任务信息列表
     */
    public List<QuartzJob> getAllJobs() throws SchedulerException {
        List<QuartzJob> jobs = null;
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        for (String groupName : scheduler.getJobGroupNames()) {
            for (JobKey jobKey : scheduler.getJobKeys(matcher)) {
                QuartzJob job = new QuartzJob();
                job.setGroupName(groupName);
                job.setJobName(jobKey.getName());
                TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), groupName);
                CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                job.setCronExpression(cronTrigger.getCronExpression());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
                if (triggerState.name().equals("NORMAL")) {
                    job.setStatus(1);
                } else {
                    job.setStatus(0);
                }
                jobs.add(job);
            }
        }
        return jobs;
    }

}

然后就是你的业务代码 当cron到的时候会自动执行

这里是我的业务代码 可以参考 这里我取了一个jobName 是我存job的时候的参数

import com.dji.sample.component.mqtt.model.TopicConst;
import com.dji.sample.component.mqtt.service.IMessageSenderService;
import com.dji.sample.dji.model.entity.AriRouteTask;
import com.dji.sample.dji.service.IAirRouteTaskService;
import com.dji.sample.dji.util.dateformat.CronExpParserUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;

public class MyJob implements Job {

    @Autowired
    private IMessageSenderService iMessageSenderService;
    @Autowired
    private IAirRouteTaskService iAirRouteTaskService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 执行自己的业务代码
//        System.out.println(context);
        String jobName = context.getJobDetail().getKey().getName();
        AriRouteTask ariRouteTask = iAirRouteTaskService.getAriRouteTask(Integer.valueOf(jobName));
        Integer type = ariRouteTask.getType();
        HashMap<Object, Object> rmqttMap = new HashMap<>();
        rmqttMap.put("code",200);
        rmqttMap.put("message","执行航线巡检任务!");
        HashMap<String, Object> data = new HashMap<>();
        data.put("taskName",ariRouteTask.getTaskName());
        data.put("filPathName",ariRouteTask.getFilPathName());
        data.put("executiveEquipment",ariRouteTask.getExecutiveEquipment());
        data.put("executiveEquipment",CronExpParserUtil.translateToChinese(ariRouteTask.getCron()));
        data.put("type",ariRouteTask.getType());
        data.put("executionTime",ariRouteTask.getCron());
        if(1 == type){
            data.put("executionTime",ariRouteTask.getExecutionTime());
        }else if (2 == type){
            data.put("executionTime",YYMMDDtoCron.convertToDateTime(ariRouteTask.getCron()));
        }
        else {
            data.put("executionTime",CronExpParserUtil.translateToChinese(ariRouteTask.getCron()));
        }
        data.put("taskId",ariRouteTask.getId());
        rmqttMap.put("data",data);
        iMessageSenderService.publishMap(TopicConst.AirRoute,rmqttMap);
    }

}

然后就是我存的job

这里可是参考 cron是前端传给我的
要注意一点就是添加的时候用quartzService.addJob(quartzJob);把他加到他的quartz里面

修改的时候我用的
quartzService.deleteJob(job); 删除job
quartzService.update(job); 这个是修改数据库的job
quartzService.addJob(job); 从新添加job到quartz
因为我修改一直未生效所以干脆直接删除在添加

//重复执行 cron表达式
            else if (3 == type){
                Map taskStrategy = (Map)map.get("taskStrategy");
                String cron = (String)taskStrategy.get("cron");
                if (true == CronUtils.isBeforeNow(cron)){
                    return ResponseResult.error("请下发当前时间之后的执行时间!");
                }
                //保存数据
                AriRouteTask ariRouteTask = new AriRouteTask();
                ariRouteTask.setFileName(airJson.getFileName());
                ariRouteTask.setTaskName(taskName);
                ariRouteTask.setFilPathName(airJson.getFilePath());
                ariRouteTask.setExecutiveEquipment(executiveEquipment);
                ariRouteTask.setCron(cron);
                ariRouteTask.setType(type);
                ariRouteTask.setRouteFileId(airJson.getId());
                ariRouteTask.setExecutionTime(CronExpParserUtil.translateToChinese(cron));
                ariRouteTask.setCreatTime(yymmdd);
                Integer rid = iAirRouteTaskService.saveTask(ariRouteTask);

                //设置定时Job
                QuartzJob quartzJob = new QuartzJob();
                quartzJob.setGroupName("QRTZ_default");
                quartzJob.setJobName(rid.toString());
                quartzJob.setJobClassName("com.dji.sample.dji.service.impl.job.MyJob");
                quartzJob.setCronExpression(cron);
                quartzJob.setStatus(1);
                quartzJob.setCreateTime(new Date());
                quartzService.addJob(quartzJob);
                //保存job到数据库
                quartzService.insert(quartzJob);

                return ResponseResult.success(ResponseResult.builder()
                        .code(200)
                        .message("下发航线巡检任务成功!")
                        .data(null)
                        .build());
            }

看下效果 其他参数可忽略 cron我传入的3秒执行一次

在这里插入图片描述

数据库刚刚修改接口设置的数据

在这里插入图片描述

然后我的业务代码是mqtt发送消息 可以看到已经三秒执行一次了 如果没有删除这个job 上面的bean就会在启动时查询出来自动执行

在这里插入图片描述

然后就是我的工具类 可以直接用

//把yyyy-MM-dd HH:mm:ss格式的字符串转换为cron格式
    public static String convertToCron(String dateTimeString) {
        try {
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date dateTime = inputFormat.parse(dateTimeString);

            SimpleDateFormat cronFormat = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
            return cronFormat.format(dateTime);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //把cron转换成 yyyy-MM-dd HH:mm:ss
    public static String convertToDateTime(String cronString) {
        try {
            SimpleDateFormat cronFormat = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
            Date dateTime = cronFormat.parse(cronString);

            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return outputFormat.format(dateTime);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

	//判断cron是当前时间之前还是之后 true之前  false之后
    public static boolean isBeforeNow(String cronExpression) {
        try {
            CronExpression cron = new CronExpression(cronExpression);
            Date nextValidTime = cron.getNextValidTimeAfter(new Date());
            return nextValidTime == null;
        } catch (Exception e) {
            return false;
        }
    }

然后这就是全部流程了 可以参考一下! 如有不对请谅解! 欢迎交流。

在这里插入图片描述

//判断cron是当前时间之前还是之后 true之前 false之后
public static boolean isBeforeNow(String cronExpression) {
try {
CronExpression cron = new CronExpression(cronExpression);
Date nextValidTime = cron.getNextValidTimeAfter(new Date());
return nextValidTime == null;
} catch (Exception e) {
return false;
}
}
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 C# 中,可以使用 Quartz.NET 来实现定时任务,同时支持数据库持久化。Quartz.NET 是一个功能强大且灵活的开源作业调度库,可以用于创建定时任务和计划任务,支持数据库持久化和集群部署等高级功能。 要使用 Quartz.NET 实现数据库持久化,需要先创建一个用于存储调度程序数据的数据库表,可以使用 Quartz.NET 提供的 SQL 脚本来创建表。然后在应用程序中配置 Quartz.NET,指定数据库类型和连接字符串等信息。示例如下: ```csharp using Quartz; using Quartz.Impl; using Quartz.Impl.AdoJobStore; using Quartz.Spi; using System; using System.Collections.Specialized; class Program { static void Main() { Console.WriteLine("Starting scheduler..."); // 创建一个调度程序实例 ISchedulerFactory schedulerFactory = new StdSchedulerFactory(GetSchedulerProperties()); IScheduler scheduler = schedulerFactory.GetScheduler().Result; // 启动调度程序 scheduler.Start(); Console.WriteLine("Scheduler started."); // 创建一个作业实例 IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("job1", "group1") .Build(); // 创建一个触发器实例,每秒钟触发一次 ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds(1) .RepeatForever()) .Build(); // 将作业和触发器添加到调度程序中 scheduler.ScheduleJob(job, trigger); // 等待用户按下 Enter 键退出 Console.ReadLine(); // 关闭调度程序 scheduler.Shutdown(); Console.WriteLine("Scheduler stopped."); } static NameValueCollection GetSchedulerProperties() { // 配置调度程序属性,指定数据库持久化和相关参数 NameValueCollection properties = new NameValueCollection(); properties["quartz.scheduler.instanceName"] = "MyScheduler"; properties["quartz.scheduler.instanceId"] = "AUTO"; properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; properties["quartz.jobStore.dataSource"] = "default"; properties["quartz.dataSource.default.provider"] = "SqlServer-20"; properties["quartz.dataSource.default.connectionString"] = "Server=(local);Database=Quartz;Trusted_Connection=True;"; return properties; } } public class HelloJob : IJob { public void Execute(IJobExecutionContext context) { Console.WriteLine("Hello, Quartz.NET!"); } } ``` 这个示例会创建一个调度程序实例,然后创建一个作业实例和触发器实例,并将它们添加到调度程序中。作业类 HelloJob 实现了 IJob 接口,用于定义作业执行的逻辑。在 GetSchedulerProperties 方法中,配置了调度程序属性,指定了数据库类型和连接字符串等信息。在这个示例中,使用的是 SQL Server 数据库。 需要注意的是,在使用 Quartz.NET 进行数据库持久化时,需要保证数据库连接可靠和高效,同时需要考虑并发执行的问题。可以适当地调整作业和触发器的参数,以达到最优的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值