springboot2.0+mybatis+postgresql9.6+quartz(修正版)
Posted 正面打爆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot2.0+mybatis+postgresql9.6+quartz(修正版)相关的知识,希望对你有一定的参考价值。
做了一个简单的定时任务。
一、依赖
<dependencies> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <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</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- spring-boot-devtools依赖包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>true</scope> </dependency> <!-- servlet 依赖. <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> --> <!-- https://mvnrepository.com/artifact/javax.servlet/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
以上依赖的版本和顺序不要随意变动,否则会出现问题
二、application.yml
spring: quartz: #相关属性配置 properties: org: quartz: scheduler: instanceName: clusteredScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate tablePrefix: QRTZ_ isClustered: true clusterCheckinInterval: 10000 useProperties: false dataSource: quartz threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 threadPriority: 5 threadsInheritContextClassLoaderOfInitializingThread: true plugin: jobInitializer: class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin fileNames: quartz_jobs.xml failOnFileNotFound: true scanInterval: 1000 wrapInUserTransaction: false #数据库方式 job-store-type: jdbc #初始化表结构 #jdbc: #initialize-schema: never datasource: druid: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://127.0.0.1:5432/quartz username: admin password: 123456 jpa: properties: hibernate: temp: use_jdbc_metadata_defaults: false ddl-auto: create #ddl-auto:设为update表示每次都不会重新建表 show-sql: true mvc: view: prefix: /WEB-INF/jsp/ suffix: .jsp http: encoding: charset: UTF-8 enabled: true force: true mybatis: mapperLocations: classpath:mapper/*.xml typeAliasesPackage: tk.mapper.model # # application: # name: quartz-cluster-node-second server: port: 8083 servlet: context-path: /test ##################################################################################################### # 打印日志 logging: level: root: INFO org.hibernate: INFO org.hibernate.type.descriptor.sql.BasicBinder: TRACE org.hibernate.type.descriptor.sql.BasicExtractor: TRACE com.springms: DEBUG com.lyw.timers.mapper: DEBUG ##################################################################################################### ###JSP ########################################################
自己根据情况修改下数据库的信息
三、一个初始化的任务
<?xml version="1.0" encoding="UTF-8"?> <job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd" version="2.0"> <pre-processing-commands> <!-- <delete-jobs-in-group>*</delete-jobs-in-group> --> <delete-triggers-in-group>*</delete-triggers-in-group> </pre-processing-commands> <processing-directives> <overwrite-existing-data>true</overwrite-existing-data> <ignore-duplicates>false</ignore-duplicates> </processing-directives> <schedule> <job> <name>PrvdDataJob</name> <group>DayEnd</group> <description>timer</description> <job-class>com.lyw.timers.PrvdDataJob</job-class> </job> <trigger> <cron> <name>PrvdDataJobTrigger</name> <group>Trigger_DayEnd</group> <job-name>PrvdDataJob</job-name> <job-group>DayEnd</job-group> <cron-expression>*/3 * * * * ?</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
同放于application.yml。
四、定义一个任务类
@Component("PrvdDataJob") public class PrvdDataJob implements Job{ static Logger logger = LoggerFactory.getLogger(PrvdDataJob.class); public PrvdDataJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { System.out.println(((CronTrigger)context.getTrigger()).getCronExpression()); // System.out.println("我的3秒一次"); } catch (Exception e) { throw new JobExecutionException("执行PrvdDataJob任务异常",e); } } }
五、一个Service类
@Service public class TimersService { @Autowired private Scheduler scheduler; @Autowired private TimerMapper timerMapper; public String setTimer(TimerVo tvo) throws Exception{ return buildTimer(tvo); } /** * 该方法用于获取到相应的任务,并进行设置 */ public String buildTimer(TimerVo tvo) throws Exception{ Timer timer = new Timer(); BeanUtils.copyProperties(tvo, timer); //查询名为triggerName的任务 timer = timerMapper.getCronTrigger(timer); //记录上一次的expression timer.setBeforeExpression(timer.getExpression()); String expression = ""; if(tvo.getMonth().length()>0) { expression = tvo.getSecord()+" "+tvo.getMinute()+" "+tvo.getHour()+" "+tvo.getDay()+" "+tvo.getMonth()+" ?"; } if(tvo.getMonth().length()<=0 && tvo.getDay().length()>0) { expression = tvo.getSecord()+" "+tvo.getMinute()+" "+tvo.getHour()+" "+tvo.getDay()+" * ?"; } if(tvo.getWeek().length()>0) { expression = tvo.getSecord()+" "+tvo.getMinute()+" "+tvo.getHour()+" ? * "+tvo.getWeek(); } timer.setExpression(expression); //设置开始时间为time秒调一次 //数据有任务触发器 if(timer.getName() != null) { //设置TriggerKey TriggerKey triggerKey = TriggerKey.triggerKey(timer.getName(), timer.getGroup()); //设置JobKey JobKey jobKey = JobKey.jobKey(timer.getJobName(), timer.getJobGroup()); //判断当前任务存在 boolean isExists = scheduler.checkExists(triggerKey); if(isExists) { //停止任务 // scheduler.pauseTrigger(triggerKey); // scheduler.pauseJob(jobKey); //更新任务时间设置 timerMapper.updateByNameAndGroup(timer); //启动任务 scheduler.resumeJob(jobKey); scheduler.resumeTrigger(triggerKey); scheduler.start(); } } return toString(timer); } public String toString(Timer timer) { String beforeExpression = timer.getBeforeExpression().replace("*", "").replace("/", "").replace("?", "").trim(); String expression = timer.getExpression().replace("*", "").replace("/", "").replace("?", "").trim(); StringBuffer sb = new StringBuffer("任务名: "+timer.getJobName()); sb.append(" <br/>"); sb.append("任务所属组: "+timer.getJobGroup()); sb.append(" <br/>"); sb.append("上一次时间设置:每 "+beforeExpression+" 秒执行一次"); sb.append(" <br/>"); sb.append("当前的时间设置:每 "+expression+" 秒执行一次"); return sb.toString(); } }
六、最后给下Timer和TimerVo类
public class TimerVo extends Timer{ private String month; private String day; private String week; private String hour; private String minute; private String secord; public String getMonth() { return month; } public void setMonth(String month) { this.month = month; } public String getDay() { return day; } public void setDay(String day) { this.day = day; } public String getWeek() { return week; } public void setWeek(String week) { this.week = week; } public String getHour() { return hour; } public void setHour(String hour) { this.hour = hour; } public String getMinute() { return minute; } public void setMinute(String minute) { this.minute = minute; } public String getSecord() { return secord; } public void setSecord(String secord) { this.secord = secord; } @Override public String toString() { return "TimerVo [month=" + month + ", day=" + day + ", week=" + week + ", hour=" + hour + ", minute=" + minute + ", secord=" + secord + "]"; } }
public class Timer { private String name; private String group; private String expression; private String jobName; private String jobGroup; private String beforeExpression; public String getBeforeExpression() { return beforeExpression; } public void setBeforeExpression(String beforeExpression) { this.beforeExpression = beforeExpression; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } public String getExpression() { return expression; } public void setExpression(String expression) { this.expression = expression; } @Override public String toString() { return "Timer [name=" + name + ", group=" + group + ", expression=" + expression + "]"; } }
七、mapper层这样写
@Repository public interface TimerMapper { @Select("select t.trigger_name,t.trigger_group,t.job_name,t.job_group,q.cron_expression from qrtz_cron_triggers q,qrtz_triggers t where 1=1 and t.trigger_name=q.trigger_name and t.trigger_name=#{name}") @Results({ @Result(property = "name", column = "trigger_name"), @Result(property = "group", column = "trigger_group"), @Result(property = "jobName", column = "job_name"), @Result(property = "jobGroup", column = "job_group"), @Result(property = "expression", column = "cron_expression") }) Timer getCronTrigger(Timer timer); @Update("update qrtz_cron_triggers set cron_expression = #{expression} where trigger_name = #{name} and trigger_group = #{group}") void updateByNameAndGroup(Timer timer); }
Controller就不再上代码了,这个就是方法调用了,相信大家都没问题。
总结:
1、问题最大的是数据库的建立,下载的quartz包中有SQL脚本,很坑的是在postgresql中不能一口气去执行。
2、版本间的依赖总算是摸索出了一套可用的,踩了不少坑。
3、cron表达式的按周,其实一般来说是带上星期几的,例如:每周一,每周三..
4、网上很多写法都是重新new了一个job,我是在数据库先查到那个任务,然后直接更新表达式,再启动一次任务,写法有些不同。
暂时就想到这么多了。
以上是关于springboot2.0+mybatis+postgresql9.6+quartz(修正版)的主要内容,如果未能解决你的问题,请参考以下文章
学习整合springboot2.0 和 mybatis,实现基本的CRUD
SpringBoot2.0 基础案例(10):整合Mybatis框架,集成分页助手插件