摘要:在項目的管理功能中,對定時任務的管理有時會很常見。但一般定時任務配置都在xml中完成,包括cronExpression表達式,十分的友善。但是如果我的任務資訊是儲存在資料庫的,想要動态的初始化,還有就是任務較多的時候不是得有一大堆的xml配置?或者說我要修改一下trigger的表達式,使原來5秒運作一次的任務變成10秒運作一次,或者說我要控制定時任務的 “ 暫停 ” 呢?暫停之後又要在某個時間點 “ 重新開機 ” 該定時任務呢?或者說直接 “ 删除 ” 該定時任務呢?要 改變某定時任務的觸發時間呢?這時問題就來了,試過在配置檔案中不傳入cronExpression等參數,但是啟動時就報錯了,難道我每次都修改xml檔案然後重新開機應用嗎,這顯然不合适的。
最理想的是在與spring整合的同時又能實作動态任務的添加、删除及修改配置,而且不需要重新開機應用。
首先我們來回顧一下spring中使用quartz的配置代碼:
<!-- 使用MethodInvokingJobDetailFactoryBean,任務類可以不實作Job接口,通過targetMethod指定調用方法-->
<bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/>
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="group" value="job_work"/>
<property name="name" value="job_work_name"/>
<!--false表示等上一個任務執行完後再開啟新的任務-->
<property name="concurrent" value="false"/>
<property name="targetObject">
<ref bean="taskJob"/>
</property>
<property name="targetMethod">
<value>execute</value>
</property>
</bean>
<!-- 排程觸發器 -->
<bean id="myTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="name" value="work_default_name"/>
<property name="group" value="work_default"/>
<property name="jobDetail">
<ref bean="jobDetail" />
</property>
<property name="cronExpression">
<value>0/5 * * * * ?</value>
</property>
</bean>
<!-- 排程工廠 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="myTrigger"/>
</list>
</property>
</bean>
所有的配置都在xml中完成,包括cronExpression表達式,十分的友善。但是如果定時任務一多并且需要手動變化時,就得有一大堆的xml配置,不友善管理。
于是在設計時我想到以下幾點
1、減少spring的配置檔案。
2、使用者可以通過頁面等方式添加、啟用、禁用某個任務。
3、使用者可以修改某個已經在運作任務的運作時間表達式,即CronExpression。
4、為友善維護,簡化任務的運作調用處理,任務的運作入口即Job實作類最好隻有一個,該Job運作類相當于工廠類,在實際調用時把任務的相關資訊通過參數方式傳入,由該工廠類根據任務資訊來具體執行需要的操作。
就像如下圖所示:
1、可在頁面直接檢視任務詳情
2、可添加、修改
3、可立即執行,并檢視執行詳情
在上面的思路下來進行我們的開發吧。
一、初始化用的資料庫腳本
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for task_detail
-- ----------------------------
DROP TABLE IF EXISTS `task_detail`;
CREATE TABLE `task_detail` (
`job_id` int(100) NOT NULL AUTO_INCREMENT,
`job_name` varchar(200) DEFAULT NULL COMMENT '任務名稱',
`job_group` varchar(100) DEFAULT NULL COMMENT '任務分組',
`job_status` varchar(5) DEFAULT NULL COMMENT '任務狀态 0禁用 1啟用 2删除',
`cron_expression` varchar(200) DEFAULT NULL COMMENT '任務運作時間表達式',
`bean_class` varchar(300) DEFAULT NULL COMMENT '任務執行類',
`execute_method` varchar(100) DEFAULT NULL COMMENT '任務執行方法',
`create_time` date DEFAULT NULL COMMENT '任務建立時間',
`update_time` date DEFAULT NULL COMMENT '任務更新時間',
`job_desc` varchar(500) DEFAULT NULL COMMENT '任務描述',
PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of task_detail
-- ----------------------------
INSERT INTO `task_detail` VALUES ('9', '測試手動設定任務', 'testQuartzTask', null, '0 0 1 * * ?', 'com.zealer.cps.task.executor.TestQuartzTask', 'printOneWord', '2017-06-22', '2017-06-22', '列印一句話');
然後建立對應的實體類ScheduleJob.java
1 package com.zealer.cps.task.value;
2
3 /**
4 * 定時任務封裝類
5 * @author xiaohe
6 */
7 public class ScheduleJob
8 {
9 /** 任務id */
10 private int jobId;
11
12 /** 任務名稱 */
13 private String jobName;
14
15 /** 任務分組 */
16 private String jobGroup;
17
18 /** 任務狀态 0禁用 1啟用 2删除*/
19 private String jobStatus;
20
21 /** 任務運作時間表達式 */
22 private String cronExpression;
23
24 /** 任務執行類 */
25 private String beanClass;
26
27 /** 任務執行方法 */
28 private String executeMethod;
29
30 /** 任務建立時間 */
31 private String createTime;
32
33 /** 任務更新時間 */
34 private String updateTime;
35
36 /** 任務描述 */
37 private String jobDesc;
38
39 //set與get方法這裡省略,大家可以自己生成
40 ......
41 }
View Code
二、spring配置檔案spring.xml
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
然後在web.xml加入
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
三、編寫任務控制器TaskController.java
1 package com.zealer.cps.task.controller;
2
3 import java.text.SimpleDateFormat;
4 import java.util.Date;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import javax.annotation.Resource;
9 import javax.servlet.http.HttpServletRequest;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.springframework.http.HttpStatus;
14 import org.springframework.http.ResponseEntity;
15 import org.springframework.stereotype.Controller;
16 import org.springframework.ui.Model;
17 import org.springframework.web.bind.annotation.ModelAttribute;
18 import org.springframework.web.bind.annotation.RequestMapping;
19 import org.springframework.web.bind.annotation.RequestMethod;
20 import org.springframework.web.bind.annotation.RequestParam;
21 import org.springframework.web.bind.annotation.ResponseBody;
22 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
23 import com.zealer.cps.base.annotation.Log;
24 import com.zealer.cps.base.constant.AppConstant;
25 import com.zealer.cps.base.controller.BaseController;
26 import com.zealer.cps.base.message.SuccessActionResult;
27 import com.zealer.cps.base.model.vo.PaginationBean;
28 import com.zealer.cps.base.util.HttpUtils;
29 import com.zealer.cps.task.manage.JobMethod;
30 import com.zealer.cps.task.service.QuartzJobService;
31 import com.zealer.cps.task.value.ScheduleJob;
32 import com.zealer.cps.task.value.ScheduleJobItem;
33 import com.zealer.cps.task.value.ScheduleJobReq;
34
35 @Controller
36 @RequestMapping( "/taskController" )
37 public class TaskController extends BaseController
38 {
39 private static Logger log = LoggerFactory.getLogger( TaskController.class );
40
41 @Resource( name = "quartzJobService" )
42 private QuartzJobService quartzJobService;
43
44 @Resource( name = "JobMethod" )
45 private JobMethod jobMethod;
46
47 @RequestMapping( "/list" )
48 @Log( "任務清單" )
49 public String listJob( @ModelAttribute("job") ScheduleJobReq jobReq, Model model, HttpServletRequest request )
50 {
51 PaginationBean<ScheduleJob> pb = quartzJobService.getJobsByPage( jobReq );
52 try {
53 pb.setUrl( HttpUtils.getRequestInfo( request, true ) );
54 } catch ( Exception e ) {
55 log.error( "get request url error", e );
56 }
57 model.addAttribute( "pb", pb );
58 return("task/taskList");
59 }
60
61
62 /**
63 * 立即執行定時任務
64 * @param job 任務實體
65 * @param model
66 * @return
67 */
68 @ResponseBody
69 @RequestMapping( value = "/executeJob", produces = "application/json;charset=utf-8" )
70 @Log( "立即執行任務" )
71 public ResponseEntity<Map<String, Object> > executeJob( ScheduleJob job, Model model )
72 {
73 jobMethod.runJobNow( job );
74 return(new ResponseEntity<Map<String, Object> > ( new HashMap<String, Object>(), HttpStatus.OK ) );
75 }
76
77
78 /**
79 * 跳轉到添加定時任務的頁面
80 * @param model
81 * 儲存結果的實體
82 */
83 @RequestMapping( value = "/addJob", method = RequestMethod.GET )
84 @Log( "初始化添加表單" )
85 public String addForm( Model model )
86 {
87 model.addAttribute( "job", new ScheduleJob() );
88 return("task/addJob");
89 }
90
91
92 /**
93 * 添加定時任務記錄
94 * @param job 任務實體
95 */
96 @RequestMapping( value = "/addJob", method = RequestMethod.POST )
97 @Log( "新增操作員" )
98 public String addUser( @ModelAttribute("job") ScheduleJob job, RedirectAttributes ra, Model model,
99 HttpServletRequest request )
100 {
101 SimpleDateFormat format = new SimpleDateFormat( AppConstant.DATE_FORMAT_YYYYMMDDHHMMSS );
102 job.setCreateTime( format.format( new Date() ) );
103 quartzJobService.inserJob( job );
104 ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
105 return("redirect:/taskController/list.do");
106 }
107
108
109 /**
110 * 初始化修改表單
111 * @param jobId
112 * @return 跳轉位址
113 */
114 @RequestMapping( value = "/updateJob", method = RequestMethod.GET )
115 @Log( "初始化修改表單" )
116 public String updateForm( @RequestParam("id") Integer jobId, Model model,
117 HttpServletRequest request )
118 {
119 ScheduleJob job = quartzJobService.getScheduleJobById( jobId );
120 model.addAttribute( "job", job );
121 return("task/updateJob");
122 }
123
124
125 /**
126 * 修改定時任務記錄資訊
127 * @param job 待修改的操作員實體
128 * @param model 封裝處理結果的實體
129 * @param request 請求對象
130 * @return 跳轉位址
131 */
132 @RequestMapping( value = "/updateJob", method = RequestMethod.POST )
133 @Log( "修改定時任務" )
134 public String updateJob( @ModelAttribute ScheduleJob job, RedirectAttributes ra, Model model,
135 HttpServletRequest request )
136 {
137 SimpleDateFormat format = new SimpleDateFormat( AppConstant.DATE_FORMAT_YYYYMMDDHHMMSS );
138 job.setUpdateTime( format.format( new Date() ) );
139 quartzJobService.updateJob( job );
140 ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
141 return("redirect:/taskController/list.do");
142 }
143
144
145 /**
146 * 删除一條定時任務記錄資訊
147 * @return
148 */
149 @RequestMapping( value = "/deleteJob" )
150 @Log( "删除任務" )
151 public String deleteJob( @RequestParam("id") int jobId, RedirectAttributes ra )
152 {
153 quartzJobService.deleteJob( jobId );
154 ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
155 return("redirect:/taskController/list.do");
156 }
157
158
159 /**
160 * 校驗執行任務的表達式是否正确
161 * @param expression
162 * @return
163 */
164 @ResponseBody
165 @RequestMapping( value = "/checkExp", produces = "application/json;charset=utf-8" )
166 @Log( "校驗任務表達式" )
167 public ResponseEntity<Map<String, Object> > checkExpression( String expression )
168 {
169 Map<String, Object> map = new HashMap<String, Object>();
170 map.put( AppConstant.SYSTEM_JSON_CODE, AppConstant.SYSTEM_JSON_ERROR );
171 if ( jobMethod.checkCron( expression ) )
172 {
173 map.put( AppConstant.SYSTEM_JSON_CODE, AppConstant.SYSTEM_JSON_SUCCESS );
174 }
175 return(new ResponseEntity<Map<String, Object> > ( map, HttpStatus.OK ) );
176 }
177
178
179 /**
180 * 某個定時任務下的所有執行記錄資訊清單
181 * @param jobReq
182 * @return
183 */
184 @RequestMapping( "/itemJob" )
185 @Log( "任務執行資訊清單" )
186 public String executeJobList( @ModelAttribute("job") ScheduleJobReq jobReq, int jobId,
187 Model model, HttpServletRequest request )
188 {
189 PaginationBean<ScheduleJobItem> pb = quartzJobService.getJobItemsByPage( jobId, jobReq );
190 try {
191 pb.setUrl( HttpUtils.getRequestInfo( request, true ) );
192 } catch ( Exception e ) {
193 log.error( "get request url error", e );
194 }
195 model.addAttribute( "pb", pb );
196 model.addAttribute( "jobId", jobId );
197 return("task/taskItemList");
198 }
199 }
四、編寫任務運作入口,即JobMethod.java
1 package com.zealer.cps.task.manage;
2
3 import java.util.List;
4
5 import javax.annotation.Resource;
6
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.quartz.CronScheduleBuilder;
10 import org.quartz.CronTrigger;
11 import org.quartz.JobBuilder;
12 import org.quartz.JobDetail;
13 import org.quartz.JobKey;
14 import org.quartz.Scheduler;
15 import org.quartz.SchedulerException;
16 import org.quartz.TriggerBuilder;
17 import org.quartz.TriggerKey;
18 import org.springframework.stereotype.Component;
19
20 import com.zealer.cps.task.QuartzJobFactory;
21 import com.zealer.cps.task.service.QuartzJobService;
22 import com.zealer.cps.task.value.ScheduleJob;
23
24
25 /**
26 * 提供Job任務相關的方法
27 * @author xiaohe
28 */
29 @Component( "JobMethod" )
30 public class JobMethod
31 {
32 @Resource( name = "schedulerFactoryBean" )
33 private Scheduler scheduler;
34
35 @Resource( name = "quartzJobService" )
36 private QuartzJobService quartzJobService;
37
38 private static Log log = LogFactory.getLog( JobMethod.class );
39
40
41 /**
42 * 任務架構初始化方法
43 * @throws
44 */
45 public void init()
46 {
47 /* 從資料庫獲得所有的任務資訊記錄 */
48 List<ScheduleJob> jobList = quartzJobService.getAllJobs();
49
50 if ( jobList != null && !jobList.isEmpty() )
51 {
52 for ( ScheduleJob scheduleJob : jobList )
53 {
54 /* 判斷任務狀态,是否為執行狀态 */
55
56 TriggerKey triggerKey = TriggerKey.triggerKey( scheduleJob
57 .getJobName(), scheduleJob.getJobGroup() );
58 CronTrigger trigger;
59 try
60 {
61 trigger = (CronTrigger) scheduler.getTrigger( triggerKey );
62 if ( null == trigger )
63 {
64 JobDetail jobDetail = JobBuilder.newJob(
65 QuartzJobFactory.class ).withIdentity(
66 scheduleJob.getJobName(),
67 scheduleJob.getJobGroup() ).build();
68
69 jobDetail.getJobDataMap().put( "scheduleJob",
70 scheduleJob );
71
72 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
73 .cronSchedule( scheduleJob.getCronExpression() );
74
75 trigger = TriggerBuilder.newTrigger().withIdentity(
76 scheduleJob.getJobName(),
77 scheduleJob.getJobGroup() ).withSchedule(
78 scheduleBuilder ).build();
79 scheduler.scheduleJob( jobDetail, trigger );
80 }else {
81 /* Trigger已存在,那麼更新相應的定時設定 */
82 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
83 .cronSchedule( scheduleJob.getCronExpression() );
84
85 /* 按新的cronExpression表達式重新建構trigger */
86 trigger = trigger.getTriggerBuilder().withIdentity(
87 triggerKey ).withSchedule( scheduleBuilder )
88 .build();
89
90 /* 按新的trigger重新設定job執行 */
91 scheduler.rescheduleJob( triggerKey, trigger );
92 }
93 }
94 catch ( SchedulerException e )
95 {
96 log.error( "Task init failed.", e );
97 }
98 }
99 }
100 }
101
102
103 /**
104 * 暫停一個job
105 *
106 * @param scheduleJob
107 * @throws SchedulerException
108 */
109 public void pauseJob( ScheduleJob scheduleJob )
110 {
111 JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
112 try
113 {
114 scheduler.pauseJob( jobKey );
115 }
116 catch ( SchedulerException e )
117 {
118 log.error( "Task pause failed.", e );
119 }
120 }
121
122
123 /**
124 * 恢複一個job
125 *
126 * @param scheduleJob
127 * @throws SchedulerException
128 */
129 public void resumeJob( ScheduleJob scheduleJob )
130 {
131 JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
132 try
133 {
134 scheduler.resumeJob( jobKey );
135 }
136 catch ( SchedulerException e )
137 {
138 log.error( "Task resume failed.", e );
139 }
140 }
141
142
143 /**
144 * 删除一個job
145 *
146 * @param scheduleJob
147 * @throws SchedulerException
148 */
149 public void deleteJob( ScheduleJob scheduleJob )
150 {
151 JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
152 try
153 {
154 scheduler.deleteJob( jobKey );
155 }
156 catch ( SchedulerException e )
157 {
158 log.error( "Task delete failed.", e );
159 }
160 }
161
162
163 /**
164 * 立即執行job
165 *
166 * @param scheduleJob
167 * @throws SchedulerException
168 */
169 public void runJobNow( ScheduleJob scheduleJob )
170 {
171 JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
172 try
173 {
174 scheduler.triggerJob( jobKey );
175 }
176 catch ( SchedulerException e )
177 {
178 log.error( "Task run failed.", e );
179 }
180 }
181
182
183 /**
184 * 更新job時間表達式
185 *
186 * @param scheduleJob
187 * @throws SchedulerException
188 */
189 public void updateJobCron( ScheduleJob scheduleJob ) throws SchedulerException
190 {
191 TriggerKey triggerKey = TriggerKey.triggerKey( scheduleJob.getJobName(),
192 scheduleJob.getJobGroup() );
193 /* 擷取trigger,即在spring配置檔案中定義的 bean id="schedulerFactoryBean" */
194 CronTrigger trigger = (CronTrigger) scheduler.getTrigger( triggerKey );
195 /* 表達式排程建構器 */
196 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule( scheduleJob
197 .getCronExpression() );
198 /*按新的cronExpression表達式重新建構trigger */
199 trigger = trigger.getTriggerBuilder().withIdentity( triggerKey )
200 .withSchedule( scheduleBuilder ).build();
201 /*按新的trigger重新設定job執行 */
202 scheduler.rescheduleJob( triggerKey, trigger );
203 }
204
205
206 /**
207 * 判斷表達式是否可用
208 * @param cron
209 * @return
210 * @throws
211 */
212 public boolean checkCron( String cron )
213 {
214 try
215 {
216 CronScheduleBuilder.cronSchedule( cron );
217 }
218 catch ( Exception e )
219 {
220 return(false);
221 }
222 return(true);
223 }
224 }
五、編寫業務層類QuartzJobService.java
1 package com.zealer.cps.task.service;
2
3 import java.util.HashMap;
4 import java.util.List;
5 import java.util.Map;
6
7 import javax.annotation.Resource;
8
9 import org.springframework.stereotype.Service;
10 import org.springframework.transaction.annotation.Propagation;
11 import org.springframework.transaction.annotation.Transactional;
12
13 import com.zealer.cps.base.dao.BaseDaoInterface;
14 import com.zealer.cps.base.model.vo.PaginationBean;
15 import com.zealer.cps.task.value.ScheduleJob;
16 import com.zealer.cps.task.value.ScheduleJobItem;
17 import com.zealer.cps.task.value.ScheduleJobReq;
18
19 @Service( "quartzJobService" )
20 public class QuartzJobService
21 {
22 public static final String JOB_LIST = "quartzJob.jobsList";
23 public static final String JOB_SELECT_BYID = "quartzJob.selectById";
24 public static final String JOB_INSERT = "quartzJob.addJob";
25 public static final String JOB_UPDATE = "quartzJob.updateJob";
26 public static final String JOB_DELETE = "quartzJob.deleteJob";
27 public static final String JOB_LIST_PAGE = "quartzJob.jobListPage";
28
29 public static final String JOBITEM_LIST_PAGE = "jobItem.selectListPageByMap";
30 public static final String JOBITEM_INSERT = "jobItem.insertJobItem";
31 public static final String JOBITEM_SELETE_BYID = "jobItem.selectByPrimaryKey";
32
33 @Resource( name = "mybatisBaseDao" )
34 private BaseDaoInterface baseDao;
35
36
37 /**
38 * 擷取所有的定時任務記錄資訊
39 * @return
40 */
41 public List<ScheduleJob> getAllJobs()
42 {
43 return(this.baseDao.queryForList( JOB_LIST, null ) );
44 }
45
46
47 /**
48 * 根據id擷取任務記錄
49 * @param id
50 * @return
51 */
52 public ScheduleJob getScheduleJobById( int id )
53 {
54 return(this.baseDao.query( JOB_SELECT_BYID, id ) );
55 }
56
57
58 /**
59 * 插入一條定時任務記錄
60 * @param job
61 */
62 public void inserJob( ScheduleJob job )
63 {
64 this.baseDao.insertData( JOB_INSERT, job );
65 }
66
67
68 /**
69 * 更新一條定時任務記錄
70 * @param job
71 */
72 public void updateJob( ScheduleJob job )
73 {
74 this.baseDao.updateData( JOB_UPDATE, job );
75 }
76
77
78 /**
79 * 删除一條定時任務記錄
80 * @param job
81 */
82 public void deleteJob( int id )
83 {
84 this.baseDao.deleteData( JOB_DELETE, id );
85 }
86
87
88 /**
89 * 分頁擷取定時任務記錄資訊
90 * @return
91 */
92 public PaginationBean<ScheduleJob> getJobsByPage( ScheduleJobReq jobReq )
93 {
94 PaginationBean<ScheduleJob> pb = new PaginationBean<ScheduleJob>( jobReq.getCurrent(), 0, jobReq.getPageSize() );
95 Map<String, Object> map = new HashMap<String, Object>();
96 map.put( "page", pb );
97 return(this.baseDao.queryForListPageByMap( JOB_LIST_PAGE, map ) );
98 }
99
100
101 /**
102 * 分頁擷取定時任務執行記錄資訊
103 * @return
104 */
105 public PaginationBean<ScheduleJobItem> getJobItemsByPage( Integer jobId, ScheduleJobReq jobReq )
106 {
107 PaginationBean<ScheduleJobItem> pb = new PaginationBean<ScheduleJobItem>( jobReq.getCurrent(), 0, jobReq.getPageSize() );
108 Map<String, Object> map = new HashMap<String, Object>();
109 map.put( "jobId", jobId );
110 map.put( "page", pb );
111 return(this.baseDao.queryForListPageByMap( JOBITEM_LIST_PAGE, map ) );
112 }
113
114
115 /**
116 * 插入一條定時任務執行記錄資訊
117 * @param jobItem
118 */
119 @Transactional( propagation = Propagation.REQUIRED )
120 public void inserJobItem( ScheduleJobItem jobItem )
121 {
122 this.baseDao.insertData( JOBITEM_INSERT, jobItem );
123 }
124
125
126 /**
127 * 根據ID擷取一條定時任務執行記錄資訊
128 * @param id
129 * @return
130 */
131 public ScheduleJobItem getScheduleJobItemById( int id )
132 {
133 return(this.baseDao.query( JOBITEM_SELETE_BYID, id ) );
134 }
135 }
六、編寫sql映射xml檔案QuartzJob.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4 <mapper namespace="quartzJob">
5 <resultMap id="jobsResultMap" type="com.lutongnet.cps.task.value.ScheduleJob">
6 <result column="job_id" property="jobId" />
7 <result column="job_name" property="jobName" />
8 <result column="job_group" property="jobGroup" />
9 <result column="job_status" property="jobStatus" />
10 <result column="cron_expression" property="cronExpression" />
11 <result column="bean_class" property="beanClass" />
12 <result column="execute_method" property="executeMethod" />
13 <result column="create_time" property="createTime" />
14 <result column="update_time" property="updateTime" />
15 <result column="job_desc" property="jobDesc" />
16 </resultMap>
17 <insert id="addJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">insert into task_detail (job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc) values (#{jobName},#{jobGroup},#{jobStatus},#{cronExpression},#{beanClass},#{executeMethod},#{createTime},#{updateTime},#{jobDesc})</insert>
18 <delete id="deleteJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">delete from task_detail where job_id = #{jobId}</delete>
19 <update id="updateJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">update task_detail
20 <set>
21 <if test="jobName != null">job_name = #{jobName},</if>
22 <if test="jobGroup != null">job_group = #{jobGroup},</if>
23 <if test="jobStatus != null">job_status = #{jobStatus},</if>
24 <if test="cronExpression != null">cron_expression = #{cronExpression},</if>
25 <if test="beanClass != null">bean_class = #{beanClass},</if>
26 <if test="executeMethod != null">execute_method = #{executeMethod},</if>
27 <if test="updateTime != null">update_time = #{updateTime},</if>
28 <if test="jobDesc != null">job_desc = #{jobDesc},</if>
29 </set>where job_id = #{jobId}</update>
30 <select id="jobListPage" resultMap="jobsResultMap" parameterType="java.util.Map">select job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc,job_id from task_detail where 1=1
31 <if test="createTime != null">and create_time = #{createTime}</if>
32 <if test="updateTime == null">and update_time = #{updateTime}</if>
33 <if test="beanClass != null">and bean_class = #{beanClass}</if>
34 <if test="executeMethod == null">and execute_method = #{executeMethod}</if>
35 <if test="jobStatus != null">and business_code = #{propertyGroups}</if>
36 <if test="jobName == null">and create_time = #{createTime}</if></select>
37 <select id="jobsList" resultMap="jobsResultMap" parameterType="java.util.Map">select job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc,job_id from task_detail</select>
38 </mapper>
七、修改和清單頁面
updateJob.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2 <%@ include file="../common/common_tags.jsp" %>
3 <!DOCTYPE html>
4 <html lang="en">
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7 <title>修改定時任務</title>
8 </head>
9 <body>
10 <div id="accordion" class="accordion">
11 <div class="accordion-group">
12 <div class="accordion-heading">
13 <div class="title">系統管理 >任務管理>修改任務</div>
14 </div>
15 <div id="addAccordion" class="accordion-body in">
16 <div class="accordion-inner" style="border: 0px solid red;">
17 <form:form action="${path}/taskController/updateJob.do" method="post" modelAttribute="job" cssClass="form-horizontal">
18 <form:hidden path="jobId"/>
19 <form:hidden path="createTime"/>
20 <div class="control-group">
21 <label class="control-label" for="jobName"><span class="help-inline input_msg_style">*</span>任務名稱</label>
22 <div class="controls">
23 <form:input path="jobName"/>
24 <span style="color:red" class="help-inline"></span>
25 </div>
26 </div>
27
28 <div class="control-group">
29 <label class="control-label" for="jobGroup"><span class="help-inline input_msg_style">*</span>任務分組</label>
30 <div class="controls">
31 <form:input path="jobGroup"/>
32 <span style="color:red" class="help-inline"></span>
33 </div>
34 </div>
35 <div class="control-group">
36 <label class="control-label"><span class="help-inline input_msg_style">*</span>任務表達式</label>
37 <div class="controls">
38 <form:input path="cronExpression"/>
39 <span style="color:red" class="help-inline"></span>
40 </div>
41 </div>
42 <div class="control-group">
43 <label class="control-label"><span class="help-inline input_msg_style">*</span>任務執行類</label>
44 <div class="controls">
45 <form:input path="beanClass"/>
46 <span style="color:red" class="help-inline"></span>
47 </div>
48 </div>
49 <div class="control-group">
50 <label class="control-label"><span class="help-inline input_msg_style">*</span>執行方法</label>
51 <div class="controls">
52 <form:input path="executeMethod"/>
53 <span style="color:red" class="help-inline"></span>
54 </div>
55 </div>
56 <div class="control-group">
57 <label class="control-label" for="jobDesc">任務描述</label>
58 <div class="controls">
59 <form:textarea path="jobDesc" rows="3" cols="20"/>
60 <span style="color:red" class="help-inline"></span>
61 </div>
62 </div>
63 <div class="form-actions">
64 <button class="lt_sys_commit" type="submit"
65 onmouseover="this.className='lt_sys_commit2'" onmouseout="this.className='lt_sys_commit'"> </button>
66 <button id="btn_back" class="lt_sys_back" type="button"
67 onmouseover="this.className='lt_sys_back2'" onmouseout="this.className='lt_sys_back'"> </button>
68 </div>
69 </form:form>
70 </div>
71 </div>
72 </div>
73 </div>
74 <script type="text/javascript" src="<w:path/>resources/js/pc.js"></script>
75 <script type="text/javascript">
76 $('#job').validate({
77 rules:{
78 jobName:{
79 required:true,
80 maxlength:50
81 },
82 jobGroup:{
83 required:true,
84 maxlength:50
85 },
86 cronExpression: {
87 required:true,
88 maxlength:200
89 },
90 beanClass: {
91 required:true,
92 maxlength:300
93 },
94 executeMethod: {
95 required:true,
96 maxlength:100
97 },
98 remark:{
99 maxlength:400,
100 }
101 },
102 messages:{
103 jobName:{
104 required:"請輸入任務名稱",
105 maxlength:"最長為50個字元",
106 },
107 jobGroup:{
108 required:"請輸入任務名稱",
109 maxlength:"最長為50個字元",
110 },
111 cronExpression:{
112 required:"請輸入執行表達式",
113 maxlength:'最長為200個字元',
114 },
115 beanClass:{
116 required:"請輸入任務執行類路徑",
117 maxlength:'最長為300個字元',
118 },
119 executeMethod:{
120 required:"請輸入執行任務的方法",
121 maxlength:'最長為100個字元',
122 },
123 remark:{
124 maxlength:"長度不能超過400個字元",
125 }
126 },
127 onfocusout: function(element) {
128 $(element).valid();
129 },
130 submitHandler: function(form){
131 var exp = $("#cronExpression").val();
132 $.post('${path}/taskController/checkExp.do',{'expression':exp},function(data)
133 {
134 if(data.code==0){
135 form.submit();
136 }else{
137 showSimpleMessage("輸入的表達式不正确,請重新輸入!");
138 $("#cronExpression").focus();
139 }
140 });
141
142 },
143 errorElement: 'span',
144 errorPlacement: function(error, element) {
145 error.appendTo(element.next());
146 }
147 });
148
149 $('#btn_back').click(function(){
150 window.location.href = '${path}/taskController/list.do';
151 })
152 </script>
153 </body>
154 </html>
taskList.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2 <%@ include file="../common/common_tags.jsp" %>
3 <!DOCTYPE html>
4 <html lang="en">
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7 <title>任務管理>任務清單</title>
8
9 </head>
10 <body>
11 <div id="accordion" class="accordion">
12 <div class="accordion-group">
13 <div class="accordion-heading">
14 <div class="title">任務管理>任務清單</div>
15 </div>
16 <div id="addAccordion" class="accordion-body in">
17 <div class="accordion-inner">
18 <div style="border: 0px solid red; height: 33px;">
19 <form:form action="${path}/taskController/list.do" method="post" modelAttribute="job" cssClass="form-inline"></form:form>
20 <lt:img menuName="任務清單" moduleName="營運管理"></lt:img>
21 </div>
22 <table class="table table-hover table-condensed">
23 <thead>
24 <tr>
25 <th width="4%"><input id="checkAll" name="checkAll" type="checkbox" style="margin-top: 0px;">全選</th>
26 <th>任務名稱</th>
27 <th>任務分組</th>
28 <th>任務描述</th>
29 <th>建立時間</th>
30 <th>更新時間</th>
31 <th>任務表達式</th>
32 <th>執行類</th>
33 <th>執行方法</th>
34 <th>操作</th>
35 </tr>
36 </thead>
37 <tbody>
38 <c:forEach items="${pb.dataList}" var="job" varStatus="status">
39 <tr>
40 <td><input name="checkItem" type="checkbox" value="${job.jobId}" style="margin-top: 0px;"></td>
41 <td>${job.jobName}</td>
42 <td>${job.jobGroup}</td>
43 <td>${job.jobDesc}</td>
44 <td>${job.createTime}</td>
45 <td>${job.updateTime}</td>
46 <td>${job.cronExpression}</td>
47 <td>${job.beanClass}</td>
48 <td>${job.executeMethod}</td>
49 <td>
50 <img src="${path}/resources/img/zengjian.png">
51 <a href="${path}/taskController/itemJob.do?jobId=${job.jobId}" >詳細</a>
52 <lt:img menuName="任務清單" moduleName="營運管理" privilegeName="執行定時任務" clickName="立即執行"
53 clickMethod="executeJob('${job.jobName}','${job.jobGroup}','${job.jobId}');"></lt:img>
54 </td>
55 </tr>
56 </c:forEach>
57 <tr>
58 <td colspan="10" form-id="job" class="paginationPanel"><ltPage:page pageBean="${pb}" /></td>
59 </tr>
60 </tbody>
61 </table>
62 </div>
63 </div>
64 </div>
65 </div>
66 <script type="text/javascript">
67
68 function executeJob(name,group,id){
69 $.ajax({
70 type: "POST",
71 url: "${path}/taskController/executeJob.do",
72 data: "jobName="+name+"&jobGroup="+group+"&jobId"+id,
73 success:function(data){
74 showSimpleMessage("定時任務已執行,執行結果請檢視詳情!");
75 }
76 });
77 }
78
79 </script>
80 </body>
81 </html>
到這裡,我們的spring3 整合quartz 2的定時任務功能終于是告一段落了,對常用的一些功能進行了實作,相信可以滿足一般項目的需求了。
每一個你不滿意的當下,都有一個你不曾努力的過去