博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring MVC Quartz 动态任务实现方式
阅读量:2168 次
发布时间:2019-05-01

本文共 35359 字,大约阅读时间需要 117 分钟。

1.项目结构

这篇文章是对上篇文章《Spring Boot Quartz 动态任务实现方式》的稍作变动, 但最终实现效果是一致的。

持久层变动:Spring Boot使用spring data jpa, Spring MVC 使用 Mybatis

2.Maven

4.0.0
com.littlefxc
learn-quartz-SpringMVC
1.0-snapshot
UTF-8
UTF-8
1.8
5.0.8.RELEASE
5.1.47
1.1.10
2.3.0
2.0.9.RELEASE
4.12
1.7.25
2.11.1
3.4.6
1.3.2
1.0
5.1.8
org.springframework
spring-framework-bom
${spring-framework-bom.version}
import
pom
org.projectlombok
lombok
1.18.4
org.springframework
spring-web
org.springframework
spring-webmvc
org.springframework
spring-aspects
aopalliance
aopalliance
${aopalliance.version}
org.springframework
spring-jdbc
org.springframework
spring-context-support
org.quartz-scheduler
quartz
${quartz.version}
slf4j-api
org.slf4j
org.quartz-scheduler
quartz-jobs
${quartz.version}
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
${mybatis-spring.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
com.alibaba
druid
${druid.version}
mysql
mysql-connector-java
${mysql.verison}
javax.servlet
javax.servlet-api
3.1.0
provided
org.springframework
spring-test
test
junit
junit
${junit.version}
org.apache.logging.log4j
log4j-slf4j-impl
${log4j2.version}
compile
org.apache.logging.log4j
log4j-core
${log4j2.version}
compile
org.apache.logging.log4j
log4j-api
${log4j2.version}
compile
org.apache.logging.log4j
log4j-web
${log4j2.version}
runtime
org.slf4j
jcl-over-slf4j
${slf4j.version}
compile
org.slf4j
slf4j-api
${slf4j.version}
compile
com.fasterxml.jackson.core
jackson-databind
2.9.7
true
org.apache.maven.plugins
maven-compiler-plugin
8
8
src/main/java
src/main/resources

3.数据库-模型

在jar包quartz-2.3.0.jar下有数据库sql文件.

sql文件的包路径地址:org.quartz.impl.jdbcjobstore,选择tables_mysql_innodb.sql

3.1. scheduler_job_info.sql

DROP TABLE IF EXISTS `scheduler_job_info`;  CREATE TABLE `scheduler_job_info`  (    `id` bigint(20) NOT NULL AUTO_INCREMENT,    `cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,    `cron_job` bit(1) NULL DEFAULT NULL,    `job_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,    `job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,    `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,    `scheduler_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,    `repeat_time` bigint(20) NULL DEFAULT NULL,    PRIMARY KEY (`id`) USING BTREE,    UNIQUE INDEX `uk_job_name`(`job_name`) USING BTREE  ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;    SET FOREIGN_KEY_CHECKS = 1;

3.2.实体类

package com.littlefxc.example.quartz.enitiy;    import lombok.Data;    import javax.persistence.*;  import java.io.Serializable;    /**  * @author fengxuechao  * @date 12/19/2018  */  @Data  @Entity  @Table(name = "scheduler_job_info")  public class SchedulerJob implements Serializable {
private static final long serialVersionUID = -8990533448070839127L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true) private String jobName; private String jobGroup; private String jobClass; private String cronExpression; private Long repeatTime; private Boolean cronJob; private String schedulerName; }

4.配置

##4.1.quartz.properties

文件应用在spring-context.xml中,详见4.3章节黄色高亮代码。
org.quartz.scheduler.instanceIdGenerator.class=com.littlefxc.example.quartz.component.CustomQuartzInstanceIdGenerator表示自定义的实例名生成策略,该类代码可以在5.1章节中看到,在数据库上的代码实际效果可以查看到(表qrtz_scheduler_state, 字段INSTANCE_NAME)。
请注意对比与上篇文章中4.1章节中的配置(application.properties)以spring.quartz.properties为前缀的属性。两者之间的区别仅在于SpringBoot以spring.quartz.properties为前缀。

# 属性 org.quartz.impl.StdSchedulerFactory  # 属性可为任何值,(最好别用DefaultQuartzScheduler),用在 JDBC JobStore 中来唯一标识实例,但是所有集群节点中必须相同  org.quartz.scheduler.instanceName=lean-quartz-SpringMVC  org.quartz.scheduler.instanceId=AUTO  org.quartz.scheduler.instanceIdGenerator.class=com.littlefxc.example.quartz.component.CustomQuartzInstanceIdGenerator  org.quartz.threadPool.threadCount=20  org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX  org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate  org.quartz.jobStore.useProperties=true  org.quartz.jobStore.misfireThreshold=60000  org.quartz.jobStore.tablePrefix=qrtz_  # 集群配置  org.quartz.jobStore.isClustered=true  org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin  org.quartz.plugin.shutdownHook.cleanShutdown=TRUE

4.2.spring-context.xml

spring-tx.xml, spring-mvc.xml的配置不是重点,以免浪费篇幅,按照你自己的个人习惯来配置.

同时我也将Druid数据源的配置省略了,请重点查看有黄色高亮的bean配置,参照上篇文章《Spring Boot Quartz 动态任务实现方式》中的配置
spring-tx.xml :配置Spring事务.
spring-mvc.xml:配置spring mvc.

... Druid数据源的配置
helperDialect=mysql reasonable=true supportMethodsArguments=true params=count=countSql rowBoundsWithCount=true autoRuntimeDialect=true

5.组件

##5.1.CustomQuartzInstanceIdGenerator

用法详见4.1章节

package com.littlefxc.example.quartz.component;    import org.quartz.SchedulerException;  import org.quartz.spi.InstanceIdGenerator;    import java.util.UUID;    /**  * @author fengxuechao  * @date 12/19/2018  */  public class CustomQuartzInstanceIdGenerator implements InstanceIdGenerator {
@Override public String generateInstanceId() throws SchedulerException {
try {
return UUID.randomUUID().toString(); } catch (Exception ex) {
throw new SchedulerException("Couldn't generate UUID!", ex); } } }

5.2.SchedulerJobFactory

Quartz与Spring结合。

在SchedulerFactory中引入Spring上下文。
用法详见4.2章节。

package com.littlefxc.example.quartz.component;    import org.quartz.spi.TriggerFiredBundle;  import org.springframework.beans.factory.config.AutowireCapableBeanFactory;  import org.springframework.context.ApplicationContext;  import org.springframework.context.ApplicationContextAware;  import org.springframework.scheduling.quartz.SpringBeanJobFactory;    /**  * 模仿了:{@link org.springframework.boot.autoconfigure.quartz.AutowireCapableBeanJobFactory}  *  * @author fengxuechao  * @date 12/19/2018  * @see 注入Spring上下文(applicationContext)  */  public class SchedulerJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } }

5.3.JobScheduleCreator

Scheduler 创建Job,SimpleTrigger,CronTrigger的封装类。

用法在service 层体现。

package com.littlefxc.example.quartz.component;    import lombok.extern.slf4j.Slf4j;  import org.quartz.CronTrigger;  import org.quartz.JobDataMap;  import org.quartz.JobDetail;  import org.quartz.SimpleTrigger;  import org.springframework.context.ApplicationContext;  import org.springframework.scheduling.quartz.CronTriggerFactoryBean;  import org.springframework.scheduling.quartz.JobDetailFactoryBean;  import org.springframework.scheduling.quartz.QuartzJobBean;  import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;  import org.springframework.stereotype.Component;    import java.text.ParseException;  import java.util.Date;    /**  * Scheduler创建Job, SimpleTrigger, CronTrigger  *  * @author fengxuechao  * @date 12/19/2018  * @see Quartz-错过触发机制  */  @Slf4j  @Component  public class JobScheduleCreator {
/** * Create Quartz Job. * * @param jobClass Class whose executeInternal() method needs to be called. * @param isDurable Job needs to be persisted even after completion. if true, job will be persisted, not otherwise. * @param context Spring application context. * @param jobName Job name. * @param jobGroup Job group. * @return JobDetail object */ public JobDetail createJob(Class
jobClass, boolean isDurable, ApplicationContext context, String jobName, String jobGroup) {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); factoryBean.setJobClass(jobClass); factoryBean.setDurability(isDurable); factoryBean.setApplicationContext(context); factoryBean.setName(jobName); factoryBean.setGroup(jobGroup); // set job data map JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put(jobName + jobGroup, jobClass.getName()); factoryBean.setJobDataMap(jobDataMap); factoryBean.afterPropertiesSet(); return factoryBean.getObject(); } /** * Create cron trigger. * * @param triggerName Trigger name. * @param startTime Trigger start time. * @param cronExpression Cron expression. * @param misFireInstruction Misfire instruction (what to do in case of misfire happens). * @return {@link CronTrigger} */ public CronTrigger createCronTrigger(String triggerName, Date startTime, String cronExpression, int misFireInstruction) {
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean(); factoryBean.setName(triggerName); factoryBean.setStartTime(startTime); factoryBean.setCronExpression(cronExpression); factoryBean.setMisfireInstruction(misFireInstruction); try {
factoryBean.afterPropertiesSet(); } catch (ParseException e) {
log.error(e.getMessage(), e); } return factoryBean.getObject(); } /** * Create simple trigger. * * @param triggerName Trigger name. * @param startTime Trigger start time. * @param repeatTime Job repeat period mills * @param misFireInstruction Misfire instruction (what to do in case of misfire happens). * @return {@link SimpleTrigger} */ public SimpleTrigger createSimpleTrigger(String triggerName, Date startTime, Long repeatTime, int misFireInstruction) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean(); factoryBean.setName(triggerName); factoryBean.setStartTime(startTime); factoryBean.setRepeatInterval(repeatTime); factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); factoryBean.setMisfireInstruction(misFireInstruction); factoryBean.afterPropertiesSet(); return factoryBean.getObject(); } }

6.Jobs

Simple Job

package com.littlefxc.example.quartz.jobs;    import lombok.extern.slf4j.Slf4j;  import org.quartz.JobExecutionContext;  import org.quartz.JobExecutionException;  import org.springframework.scheduling.quartz.QuartzJobBean;    import java.util.stream.IntStream;    /**  * @author fengxuechao  * @date 12/19/2018  */  @Slf4j  public class SimpleJob extends QuartzJobBean {
@Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.info("{} Start................", context.getJobDetail().getKey()); IntStream.range(0, 5).forEach(i -> {
log.info("Counting - {}", i); try {
Thread.sleep(1000); } catch (InterruptedException e) {
log.error(e.getMessage(), e); } }); log.info("{} End................", context.getJobDetail().getKey()); } }

Cron Job

package com.littlefxc.example.quartz.jobs;    import lombok.extern.slf4j.Slf4j;  import org.quartz.DisallowConcurrentExecution;  import org.quartz.JobExecutionContext;  import org.quartz.JobExecutionException;  import org.springframework.scheduling.quartz.QuartzJobBean;    import java.util.stream.IntStream;    /**  * @author fengxuechao  * @date 12/19/2018  */  @Slf4j  @DisallowConcurrentExecution // 这个注解告诉Quartz,一个给定的Job定义(也就是一个JobDetail实例),不并发运行。  public class SampleCronJob extends QuartzJobBean {
@Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.info("{} Start................", context.getJobDetail().getKey()); IntStream.range(0, 10).forEach(i -> {
log.info("Counting - {}", i); try {
Thread.sleep(1000); } catch (InterruptedException e) {
log.error(e.getMessage(), e); } }); log.info("{} End................", context.getJobDetail().getKey()); } }

7.控制器层

7.1.QuartzController

工作调度的主要代码。

与上篇文章《Spring Boot Quartz 动态任务实现方式》的不同点在于queryjob()方法,直接使用了pageNum, pageSize而不是Pageable(Spring data jpa 自带分页类)

package com.littlefxc.example.quartz.controller;    import com.github.pagehelper.PageInfo;  import com.littlefxc.example.quartz.enitiy.SchedulerJob;  import com.littlefxc.example.quartz.service.SchedulerService;  import lombok.extern.slf4j.Slf4j;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.web.bind.annotation.*;    import java.util.Map;    /**  * @author fengxuechao  * @date 12/19/2018  **/  @RestController  @RequestMapping("/job")  @Slf4j  public class QuartzController {
private final SchedulerService schedulerService; @Autowired public QuartzController(SchedulerService schedulerService) {
this.schedulerService = schedulerService; } /** * 添加 * * @param jobInfo */ @PostMapping(value = "/addjob") public void addjob(@RequestBody SchedulerJob jobInfo) {
schedulerService.scheduleNewJob(jobInfo); } /** * 暂停 * * @param jobName * @param jobGroup */ @PostMapping(value = "/pausejob") public void pausejob( @RequestParam String jobName, @RequestParam String jobGroup) {
schedulerService.pauseJob(jobName, jobGroup); } /** * 恢复启动 * * @param jobName * @param jobGroup */ @PostMapping(value = "/resumejob") public void resumejob(@RequestParam String jobName, @RequestParam String jobGroup) {
schedulerService.resumeJob(jobName, jobGroup); } /** * 更新:移除older trigger,添加new trigger * * @param jobInfo */ @PostMapping(value = "/reschedulejob") public void rescheduleJob(@RequestBody SchedulerJob jobInfo) {
schedulerService.updateScheduleJob(jobInfo); } /** * 删除 * * @param jobName * @param jobGroup */ @PostMapping(value = "/deletejob") public void deletejob(@RequestParam String jobName, @RequestParam String jobGroup) {
schedulerService.deleteJob(jobName, jobGroup); } /** * 查询 * * @param pageNum default 1 * @param pageSize default 10 * @param cron true:cron trigger, false:simple trigger * @return */ @GetMapping(value = "/queryjob") public PageInfo
> queryjob( @RequestParam(defaultValue = "0") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam Boolean cron) {
return schedulerService.findAll(cron, pageNum, pageSize); } }

7.2.SchedulerController

仅对自定义数据库(scheduler_job_info)操作的控制器。

package com.littlefxc.example.quartz.controller;    import com.littlefxc.example.quartz.enitiy.SchedulerJob;  import com.littlefxc.example.quartz.service.SchedulerService;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.web.bind.annotation.GetMapping;  import org.springframework.web.bind.annotation.RequestMapping;  import org.springframework.web.bind.annotation.RequestParam;  import org.springframework.web.bind.annotation.RestController;    /**  * @author fengxuechao  * @date 12/20/2018  **/  @RestController  @RequestMapping("/job-info")  public class SchedulerController {
@Autowired private SchedulerService schedulerService; /** * 根据jobName查询 * @param jobName * @return {@link SchedulerJob} */ @GetMapping("/findOne") public SchedulerJob findOne(@RequestParam String jobName) {
return schedulerService.findOne(jobName); } }

8.Service层

##8.1.SchedulerServiceImpl

package com.littlefxc.example.quartz.service.impl;    import com.github.pagehelper.PageInfo;  import com.littlefxc.example.quartz.component.JobScheduleCreator;  import com.littlefxc.example.quartz.dao.SchedulerDao;  import com.littlefxc.example.quartz.enitiy.SchedulerJob;  import com.littlefxc.example.quartz.service.SchedulerService;  import lombok.extern.slf4j.Slf4j;  import org.apache.ibatis.session.RowBounds;  import org.quartz.*;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.context.ApplicationContext;  import org.springframework.scheduling.quartz.QuartzJobBean;  import org.springframework.scheduling.quartz.SchedulerFactoryBean;  import org.springframework.stereotype.Service;  import org.springframework.transaction.annotation.Transactional;    import java.util.Date;  import java.util.List;  import java.util.Map;    /**  * @author fengxuechao  * @date 12/19/2018  */  @Slf4j  @Service  @Transactional(rollbackFor = Exception.class)  public class SchedulerServiceImpl implements SchedulerService {
@Autowired private SchedulerFactoryBean schedulerFactoryBean; @Autowired private SchedulerDao schedulerDao; @Autowired private ApplicationContext context; @Autowired private JobScheduleCreator scheduleCreator; /** * 启动所有的在表scheduler_job_info中记录的job */ @Override public void startAllSchedulers() {
List
jobInfoList = schedulerDao.findAll(); if (jobInfoList != null) {
Scheduler scheduler = schedulerFactoryBean.getScheduler(); jobInfoList.forEach(jobInfo -> {
try {
JobDetail jobDetail = JobBuilder.newJob((Class
) Class.forName(jobInfo.getJobClass())) .withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup()).build(); if (!scheduler.checkExists(jobDetail.getKey())) {
Trigger trigger; jobDetail = scheduleCreator.createJob((Class
) Class.forName(jobInfo.getJobClass()), false, context, jobInfo.getJobName(), jobInfo.getJobGroup()); if (jobInfo.getCronJob() && CronExpression.isValidExpression(jobInfo.getCronExpression())) {
trigger = scheduleCreator.createCronTrigger(jobInfo.getJobName(), new Date(), jobInfo.getCronExpression(), CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); } else {
trigger = scheduleCreator.createSimpleTrigger(jobInfo.getJobName(), new Date(), jobInfo.getRepeatTime(), SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT); } scheduler.scheduleJob(jobDetail, trigger); } } catch (ClassNotFoundException e) {
log.error("Class Not Found - {}", jobInfo.getJobClass(), e); } catch (SchedulerException e) {
log.error(e.getMessage(), e); } }); } } @Override public void scheduleNewJob(SchedulerJob jobInfo) {
try {
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobDetail jobDetail = JobBuilder.newJob((Class
) Class.forName(jobInfo.getJobClass())) .withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup()).build(); if (!scheduler.checkExists(jobDetail.getKey())) {
jobDetail = scheduleCreator.createJob((Class
) Class.forName(jobInfo.getJobClass()), false, context, jobInfo.getJobName(), jobInfo.getJobGroup()); Trigger trigger; if (jobInfo.getCronJob()) {
trigger = scheduleCreator.createCronTrigger(jobInfo.getJobName(), new Date(), jobInfo.getCronExpression(), CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); } else {
trigger = scheduleCreator.createSimpleTrigger(jobInfo.getJobName(), new Date(), jobInfo.getRepeatTime(), SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT); } scheduler.scheduleJob(jobDetail, trigger); jobInfo.setSchedulerName(schedulerFactoryBean.getScheduler().getSchedulerName()); schedulerDao.save(jobInfo); } else {
log.error("scheduleNewJobRequest.jobAlreadyExist"); } } catch (ClassNotFoundException e) {
log.error("Class Not Found - {}", jobInfo.getJobClass(), e); } catch (SchedulerException e) {
log.error(e.getMessage(), e); } } @Override public void updateScheduleJob(SchedulerJob jobInfo) {
Trigger newTrigger; System.out.println(jobInfo); if (jobInfo.getCronJob()) {
newTrigger = scheduleCreator.createCronTrigger(jobInfo.getJobName(), new Date(), jobInfo.getCronExpression(), CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); } else {
newTrigger = scheduleCreator.createSimpleTrigger(jobInfo.getJobName(), new Date(), jobInfo.getRepeatTime(), SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT); } try {
schedulerFactoryBean.getScheduler().rescheduleJob(TriggerKey.triggerKey(jobInfo.getJobName()), newTrigger); jobInfo.setSchedulerName(schedulerFactoryBean.getScheduler().getSchedulerName()); schedulerDao.save(jobInfo); } catch (SchedulerException e) {
log.error(e.getMessage(), e); } } /** * unscheduleJob(TriggerKey triggerKey)只是不再调度触发器,所以,当其他的触发器引用了这个Job,它们不会被改变 * * @param jobName * @return */ @Override public boolean unScheduleJob(String jobName) {
try {
return schedulerFactoryBean.getScheduler().unscheduleJob(new TriggerKey(jobName)); } catch (SchedulerException e) {
log.error("Failed to un-schedule job - {}", jobName, e); return false; } } /** * deleteJob(JobKey jobKey):
* 1.循环遍历所有引用此Job的触发器,以取消它们的调度(to unschedule them)
* 2.从jobstore中删除Job * * @param jobName job name * @param jobGroup job group * @return */ @Override public boolean deleteJob(String jobName, String jobGroup) {
try {
boolean deleteJob = schedulerFactoryBean.getScheduler().deleteJob(new JobKey(jobName, jobGroup)); if (deleteJob) {
SchedulerJob job = schedulerDao.findSchedulerJobByJobName(jobName); schedulerDao.deleteByJobName(jobName); } return deleteJob; } catch (SchedulerException e) {
log.error("Failed to delete job - {}", jobName, e); return false; } } /** * 暂停 * * @param jobName job name * @param jobGroup job group * @return */ @Override public boolean pauseJob(String jobName, String jobGroup) {
try {
schedulerFactoryBean.getScheduler().pauseJob(new JobKey(jobName, jobGroup)); return true; } catch (SchedulerException e) {
log.error("Failed to pause job - {}", jobName, e); return false; } } /** * 恢复 * * @param jobName job name * @param jobGroup job group * @return */ @Override public boolean resumeJob(String jobName, String jobGroup) {
try {
schedulerFactoryBean.getScheduler().resumeJob(new JobKey(jobName, jobGroup)); return true; } catch (SchedulerException e) {
log.error("Failed to resume job - {}", jobName, e); return false; } } @Override public boolean startJobNow(String jobName, String jobGroup) {
try {
schedulerFactoryBean.getScheduler().triggerJob(new JobKey(jobName, jobGroup)); return true; } catch (SchedulerException e) {
log.error("Failed to start new job - {}", jobName, e); return false; } } @Transactional(readOnly = true) @Override public PageInfo
> findAll(Boolean cron, Integer pageNum, Integer pageSize) {
List
> list; if (cron) {
list = schedulerDao.getJobWithCronTrigger(new RowBounds(pageNum, pageSize)); } else {
list = schedulerDao.getJobWithSimpleTrigger(new RowBounds(pageNum, pageSize)); } return new PageInfo<>(list); } @Transactional(readOnly = true) @Override public SchedulerJob findOne(String jobName) {
return schedulerDao.findSchedulerJobByJobName(jobName); } }

9.Dao层

9.1.SchedulerDao

package com.littlefxc.example.quartz.dao;    import com.littlefxc.example.quartz.enitiy.SchedulerJob;  import org.apache.ibatis.session.RowBounds;  import org.springframework.stereotype.Repository;    import java.util.List;  import java.util.Map;    /**  * @author fengxuechao  * @date 12/19/2018  */  @Repository  public interface SchedulerDao {
/** * 仅查询simple trigger关联的Job * 不查询cron trigger关联的job * * @param rowBounds 分页插件 * @return */ List
> getJobWithSimpleTrigger(RowBounds rowBounds); /** * 仅查询cron trigger关联的Job * 不查询simple trigger关联的job * * @param rowBounds 分页插件 * @return */ List
> getJobWithCronTrigger(RowBounds rowBounds); /** * 根据JobName查询SchedulerJob * * @param jobName * @return SchedulerJob */ SchedulerJob findSchedulerJobByJobName(String jobName); List
findAll(); /** * 保存和更新 * 当id==null时,更新 * @param jobInfo * @return */ Integer save(SchedulerJob jobInfo); Integer deleteByJobName(String jobName); }

9.2.SchedulerDao.xml

cron_expression,cron_job,job_class,job_group,job_name,repeat_time, scheduler_name
delete from scheduler_job_info where job_name = #{jobName} and scheduler_name = 'scheduler-spring-mvc'
insert into scheduler_job_info(
) values(#{cronExpression}, #{cronJob}, #{jobClass}, #{jobGroup}, #{jobName}, #{repeatTime}, 'scheduler-spring-mvc')
update scheduler_job_info
cron_expression = #{cronExpression}
cron_job = #{cronJob}
job_class = #{jobClass}
job_group = #{jobGroup}
job_name = #{jobName}
repeat_time = #{repeatTime}
scheduler_name = #{schedulerName}
id = #{id}

10.网页Vue+ElementUI实现

网页基本没什么变化,参考上篇文章

11. 引用

你可能感兴趣的文章
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>
使聊天机器人具有个性
查看>>
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>