java项目中常用的定时任务实现方法

在系统开发中,定时任务是很多时候都会遇到的需求,就我个人而言,定时任务可以通过两种方法实现,一种是数据库层面的,一种是代码层面的,这里简单介绍一下两种方式:

一、数据库实现定时任务

1.oracle数据:

declare
  job number;
BEGIN
  DBMS_JOB.SUBMIT(  
        JOB => job,  /*自动生成JOB_ID*/  
        WHAT => 'CHONG_ZHI_TI_JIAN_XU_HAO();',  /*需要执行的存储过程名称或SQL语句*/  
        NEXT_DATE => sysdate,  /*初次执行时间-立即执行*/  
        INTERVAL => 'trunc(sysdate)+1'/*每隔1天执行一次*/
      );  
  commit;
end;

2.mysql数据库:
1).查看mysql事件调度器是否开启 OFF/ON:

show variables like '%event_scheduler%'; 

2).如果没有开启则开启事件调度器,执行以下任一SQL语句即可:

SET GLOBAL event_scheduler = ON; 
SET @@global.event_scheduler = ON; 
SET GLOBAL event_scheduler = 1; 
SET @@global.event_scheduler = 1;

3).创建定时任务:

CREATE EVENT IF NOT EXISTS CHONG_ZHI_TI_JIAN_XU_HAO   -- 定时任务名称
    ON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 5 MINUTE)
    ON COMPLETION PRESERVE ENABLE   
		COMMENT '每天的00:05分执行定时任务'
    DO UPDATE REG_TI_JIAN_HAO_XU_HAO SET XU_HAO = 1;-- DO 后面是需要执行的SQL语句

查看定时任务:

SELECT * FROM information_schema.events; 

关闭定时任务:

DROP event 定时任务名称;

二、springboot实现定时任务

我这里使用的都是corn表达式,在线corn生成:http://cron.qqe2.com/

温馨提示:使用corn表达式的时候,在线生成有7位,而程序中使用只能有6位,所有需要去掉最后一位表示年份的就可以了。
如:生成0 5 0 * * ? * ,程序中使用 0 5 0 * * ? 就行了。

1.使用@Schedule注解,适用于简单定时任务
1).创建一个 Spring Boot 项目,并且添加 web 依赖 spring-boot-starter-web

2).在启动类上添加 @EnableScheduling 注解,开启定时任务:

@SpringBootApplication
@EnableScheduling // 开始定时任务
@EnableTransactionManagement // 开启事务管理
public class PeisTimerTestApplication {
	public static void main(String[] args) {
		SpringApplication.run(PeisTimerTestApplication.class, args);
	}

}

3).编写任务类:

@Component
public class TiJianHaoXuHaoSchedule {

	@Autowired
	private TiJianHaoXuHaoService tiJianHaoXuHaoService;
	
	@Scheduled(cron = "0 5 0 1/1 * ?") //每天凌晨00:05分执行
	public void chongZhiTiJianHaoXuHao() {
		tiJianHaoXuHaoService.updateTiJianHaoXuHao();
	}
}

到此就完成了一个简单的定时任务了。

2.使用Quartz,可以处理复杂的定时任务
使用Quartz,有两种方式,一种是自己写任务类,另一种是继承QuartzJobBean写任务类(这种方式可以传递参数)。
1).创建一个 Spring Boot 项目,并且在maven中添加spring-boot-starter-quartz依赖

2).在启动类上添加 @EnableScheduling 注解,开启定时任务

3).实现任务类:
方式一:自己写job类:

@Component
public class TiJianHaoXuHaoSchedule2 {

	@Autowired
	private TiJianHaoXuHaoService tiJianHaoXuHaoService;

	@Scheduled(cron = "0 5 0 1/1 * ?") //每天凌晨00:05分执行
	public voidchongZhiTiJianHaoXuHao() {
		tiJianHaoXuHaoService.updateTiJianHaoXuHao();
	}
}

编写配置类:

@Configuration
public class QuartzConfig {
	@Bean
	MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetBeanName("chongZhiTiJianHaoXuHaoJob2");// 自定义任务类bean名称
		bean.setTargetMethod("chongZhiTiJianHaoXuHao");// 执行定时任务的方法
		return bean;
	}
	@Bean
	CronTriggerFactoryBean cronTrigger2() {
		CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
		bean.setCronExpression("0 5 0 1/1 * ?");
		bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
		return bean;
	}
	@Bean
	SchedulerFactoryBean schedulerFactoryBean() {
		SchedulerFactoryBean bean = new SchedulerFactoryBean();
		bean.setTriggers(cronTrigger2().getObject());
		return bean;
	}
}

方式二:继承QuartzJobBean写任务类(这种方式可以传递参数):

public class ChongZhiTiJianHaoXuHaoJob extends QuartzJobBean {

	private TiJianHaoXuHaoService tiJianHaoXuHaoService;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		tiJianHaoXuHaoService.updateTiJianHaoXuHao();
	}

	// 需要提供setter方法
	public void setTiJianHaoXuHaoService(TiJianHaoXuHaoService tiJianHaoXuHaoService) {
		this.tiJianHaoXuHaoService = tiJianHaoXuHaoService;
	}

}

编写配置类:

@Configuration
public class QuartzConfig {
	@Bean
	JobDetailFactoryBean jobDetailFactoryBean() {
		JobDetailFactoryBean bean = new JobDetailFactoryBean();
		bean.setJobClass(ChongZhiTiJianHaoXuHaoJob.class);
		JobDataMap map = new JobDataMap();
		map.put("tiJianHaoXuHaoService", tiJianHaoXuHaoService());
		bean.setJobDataMap(map);
		return bean;
	}

	@Bean
	CronTriggerFactoryBean cronTrigger() {
		CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
		bean.setCronExpression("0 5 0 1/1 * ?");
		bean.setJobDetail(jobDetailFactoryBean().getObject());
		return bean;
	}

	@Bean
	SchedulerFactoryBean schedulerFactoryBean() {
		SchedulerFactoryBean bean = new SchedulerFactoryBean();
		bean.setTriggers(cronTrigger().getObject());
		return bean;
	}

	@Bean
	TiJianHaoXuHaoService tiJianHaoXuHaoService() {
		return new TiJianHaoXuHaoServiceImpl();
	}
}

以上就是系统中常用的定时任务了。