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("\r\n<br/>");
		sb.append("任务所属组: "+timer.getJobGroup());
		sb.append("\r\n<br/>");
		sb.append("上一次时间设置:每 "+beforeExpression+" 秒执行一次");
		sb.append("\r\n<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,我是在数据库先查到那个任务,然后直接更新表达式,再启动一次任务,写法有些不同。

暂时就想到这么多了。

原文地址:https://www.cnblogs.com/yulonglyw/p/9260548.html

时间: 2024-11-01 00:53:59

springboot2.0+mybatis+postgresql9.6+quartz(修正版)的相关文章

springboot2.0+mybatis多数据源集成

最近在学springboot,把学的记录下来.主要有springboot2.0+mybatis多数据源集成,logback日志集成,springboot单元测试. 一.代码结构如下 二.pom.xml文件如下 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation

RT-thread v2.0.1修正版

RT-Thread v2.0.1是v2.0.0正式版这个系列的bug修正版.RT-Thread v2.0.1修正的主要内容包括: IAR用的dlib,加入THREAD_SUPPORT 和 FILE_DESCRIPTOR的支持: 修正finsh中echo回显模式的问题: 修正USB host代码的编译错误: 修正sensor框架回调函数的问题: 修正pin设备注册时的设备名称问题:

SpringBoot2.0之四 简单整合MyBatis

从最开始的SSH(Struts+Spring+Hibernate),到后来的SMM(SpringMVC+Spring+MyBatis),到目前的S(SpringBoot),随着框架的不断更新换代,也为我们广大的程序猿提供了更多的方便,一起搭建一个从控制层到持久层的项目可能需要一两天的时间,但是采用SpringBoot的方式,我们可能只需要10分钟就能轻松完成一个web项目的搭建,下面我们介绍一下SpringBoot2.0整合MyBatis的方法 一.新建一个项目,引入相关依赖 <!-- 单元测试

SpringBoot2.0 基础案例(10):整合Mybatis框架,集成分页助手插件

一.Mybatis框架 1.mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型.接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录. 2.mybatis特点 1)sql语句与代码分离,存放于xml配置文件中,方便管理 2)用逻辑标签

CloudFoundry.yml修正版

--- name: CFRELEASE02 director_uuid: fdd46e30-f2c5-41dc-9662-0976fdac5716 releases: - name: cf version: 171 meta: environment: null stemcell: name: bosh-vsphere-esxi-ubuntu version: 2366 compilation: workers: 2 cloud_properties: ram: 1024 disk: 6144

基于BranchTraceStore机制的CPU执行分支追踪工具 —— CpuWhere [修正版 仅驱动]

[前言] 在张银奎老师的<软件调试>一书中,详细地讲解了使用内存的分支记录机制——BTS机制(5.3),并且给出了示例工具CpuWhere及其源代码.但实际运行(VMware XP_SP3 单核)并没有体现应有的效果,无法读取到分支记录.查看了源代码并没有发现任何问题,与书中所讲一致.既然软件本身没有问题,那会不会是在虚拟机中运行的问题呢? 翻出了闲置多年的老机器,奔腾Dual+XP_SP3,在启动配置中增加/numproc=1,设置单核启动,测试结果依然没有什么改变.网上搜索几遍也是无果,毕

css3弹性盒子模型之box-flex(修正版一)

http://www.rainleaves.com/html/1095.html css3弹性盒子模型之box-flex(修正版一) 发表于 2011/12/06 9 条回复 18,699 views 今天看到蓝色理想上面有一篇文章讲<css3弹性盒模型布局模块介绍>里面讲到用box-flex,突然觉得有点心慌,上次看到响应式网页设计里面也同样讲到flex box自适应布局,而上次竟然没有引起自己的注意,想深入研究一下,竟然给忘记了,于是就在这种不断的忘记中彻底变成outer.今天借此机会,好

Win7全自动精简批处理_温柔处理极速修正版/暴力剩女工程测试版

2011htpcfans 发表于 2012-5-11 http://bbs.wuyou.net/forum.php?mod=viewthread&tid=210269&highlight=win7%2B%BE%AB%BC%F2 2012-5-5 08:45  本人仓促发布了Win7全自动精简批处理_温柔处理版,经过一周改进优化,现发布新版:Win7全自动精简批处理_温柔处理极速修正版/暴力剩女工程测试版.    强烈建议,大家先看完说明. 应部分坛友要求,我把本批处理的设计背景.执行效果.

如何把程序钉到Windows7任务栏(修正版)

源:如何把程序钉到Windows7任务栏(修正版) 在CSDN论坛看到有网友提问如何把程序钉到Windows7的任务栏,ccrun(妖哥)对这个问题很感兴趣,于是google了一下,没有找到相关的API资料,但是在国外的一个站点看到用FolderItemVerb对象来实现的方法,关于具体的资料,可以查阅MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/bb774172(v=vs.85).aspx 在Delphi中实现的代码