源碼地址:https://gitee.com/seek412/quartz03.git
在上一章節中介紹了spring整合quartz定時任務,但是想要修改、停止定時任務就必須重啓服務器。實際需求往往更復雜,下面介紹如何在前端頁面控制定時任務的啓動,暫停,修改定時任務的時間等
項目結構
步驟1:數據庫設計
在上一章介紹了spring整合quartz,下面是配置文件
<!-- class文件對應定時任務的路徑,如果有多個定時任務就配置多個 -->
<bean id="quartzJobA" class="com.demo.schedule.QuartzJobA"/>
<bean id="quartzJobB" class="com.demo.schedule.QuartzJobB"/>
<bean id="jobDetailA" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 這裏的name必須是targetObject和targetMethod -->
<property name="targetObject" ref="quartzJobA"/>
<property name="targetMethod" value="jobA"/>
</bean>
<bean id="jobDetailB" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="quartzJobB"/>
<property name="targetMethod" value="jobB"/>
</bean>
<!-- 定義觸發的條件 -->
<bean id="jobTriggerA" class="org.springframework.scheduling.quartz.CronTriggerBean">
<!-- 這裏的name必須是jobDetail和cronExpression -->
<property name="jobDetail" ref="jobDetailA"/>
<!-- 每隔5秒執行一次 -->
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<bean id="jobTriggerB" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetailB"/>
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<!-- 總管理類,如果將lazy-init='false',那麼容器啓動就會執行調度程序 -->
<bean id="startQuartz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="jobTriggerA"/>
<ref bean="jobTriggerB"/>
</list>
</property>
</bean>
從上面的配置文件中我們可以看到,有如下字段需要我們指定:
bean id
bean class:需要執行的定時任務的路徑
targetMethod:需要執行的定時任務的方法
Expression:定時任務執行頻率
設計數據庫字段如下:
CREATE TABLE `schedule_job` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
`job_name` varchar(255) DEFAULT NULL COMMENT '任務名',
`job_group` varchar(255) DEFAULT NULL COMMENT '任務組',
`method_name` varchar(255) DEFAULT NULL COMMENT '要執行的方法',
`bean_class` varchar(255) DEFAULT NULL COMMENT '定時任務所在的類路徑',
`status` int(11) DEFAULT NULL COMMENT '任務狀態 0:正常 1:暫停',
`cron_expression` varchar(255) DEFAULT NULL COMMENT '時間表達式',
`params` varchar(255) DEFAULT NULL COMMENT '參數',
`remark` varchar(255) DEFAULT NULL COMMENT '備註',
`create_time` datetime DEFAULT NULL COMMENT '創建時間',
`modify_time` datetime DEFAULT NULL COMMENT '修改時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
步驟2:搭建ssm開發環境
2.1 引入依賴包
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>quartz03</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>quartz03 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 引入項目依賴的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring面向切面編程 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!-- mybatis與spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mybatis逆向工程-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<!-- pageHelper分頁插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
<!-- 數據庫連接池druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<!-- 數據庫驅動包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--servlet相關-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 引入org.apache.commons.lang包-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- quartz作業調度-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<!-- json解析 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.4</version>
</dependency>
</dependencies>
<build>
<finalName>quartz03</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
2.2 添加配置文件
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 1. 配置數據庫配置文件 -->
<bean id = "property" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<!-- 2. 使用druid連接數據庫 -->
<bean id = "dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method = "close">
<!-- 數據庫基本信息配置 -->
<property name = "url" value = "${url}" />
<property name = "username" value = "${username}" />
<property name = "password" value = "${password}" />
<property name = "driverClassName" value = "${driverClassName}" />
<property name = "filters" value = "${filters}" />
<!-- 最大併發連接數 -->
<property name = "maxActive" value = "${maxActive}" />
<!-- 初始化連接數量 -->
<property name = "initialSize" value = "${initialSize}" />
<!-- 配置獲取連接等待超時的時間 -->
<property name = "maxWait" value = "${maxWait}" />
<!-- 最小空閒連接數 -->
<property name = "minIdle" value = "${minIdle}" />
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name = "timeBetweenEvictionRunsMillis" value ="${timeBetweenEvictionRunsMillis}" />
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name = "minEvictableIdleTimeMillis" value ="${minEvictableIdleTimeMillis}" />
<!-- 用來檢測連接是否有效sql,要求是一個查詢語句 -->
<property name = "validationQuery" value = "${validationQuery}" />
<!-- 建議配置爲true,不影響性能,並且保證安全性 -->
<property name = "testWhileIdle" value = "${testWhileIdle}" />
<!-- 申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能 -->
<property name = "testOnBorrow" value = "${testOnBorrow}" />
<!-- 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能 -->
<property name = "testOnReturn" value = "${testOnReturn}" />
<!-- 要啓用PSCache,必須配置大於0 -->
<property name = "maxOpenPreparedStatements" value ="${maxOpenPreparedStatements}" />
<!-- 打開 removeAbandoned 功能 -->
<property name = "removeAbandoned" value = "${removeAbandoned}" />
<!-- 1800 秒,也就是 30 分鐘 -->
<property name = "removeAbandonedTimeout" value ="${removeAbandonedTimeout}" />
<!-- 關閉 abanded 連接時輸出錯誤日誌 -->
<property name = "logAbandoned" value = "${logAbandoned}" />
</bean>
<!-- 3. 啓用自動掃描 -->
<context:component-scan base-package="com.demo.*">
<!-- 排除註解爲controller的類型 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 4. 配置和mybatis的整合 -->
<bean id = "sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis的全局文件位置 -->
<property name="configLocation" value="classpath:mybatis.xml"/>
<property name="dataSource" ref="dataSource"/>
<!-- 指定mybatis的mapper文件 -->
<property name="mapperLocations">
<list>
<value>classpath:/mapper/*.xml</value>
</list>
</property>
</bean>
<!-- 5. 配置掃描器,將mybatis接口的實現加入到ioc容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 掃描所有dao接口的實現,加入到 ioc容器中 -->
<property name="basePackage" value="com.demo.dao"/>
</bean>
<!-- 6. 事務控制 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 控制住數據源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 7. 開啓基於註解的事務,使用xml配置形式的事務 -->
<aop:config>
<!-- 切入點表達式 -->
<aop:pointcut expression="execution(* com.demo.service..*(..))" id="txPoint"/>
<!-- 配置事務增強 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<!-- 8. 配置事務增強,也就是事務如何切入 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有的方法都是事務方法 -->
<tx:method name="*"/>
<!-- 以get開始的所有方法 -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
<bean id = "springContextUtils" class="com.demo.common.utils.SpringContextUtils"/>
<!--9. Quartz定時任務動態配置 -->
<bean id = "schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/>
</beans>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- 1. 註解探測器 -->
<context:component-scan base-package="com.demo.controller">
</context:component-scan>
<!-- 2. 配置視圖解析器,方便頁面返回-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 3.兩個標準配置 -->
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
</beans>
mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 1. 駝峯規則命名 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 2. 別名 -->
<typeAliases>
<typeAlias type="com.demo.domain.ScheduleJob" alias="ScheduleJob"/>
</typeAliases>
<!-- 3. 引入分頁插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
</configuration>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Archetype Created Web Application</display-name>
<!-- 1. 啓動spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2. springmvc前端控制器,攔截所有請求 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<!-- 3. 字符編碼過濾器配置 ,字符過濾器要放在所有過濾器的前面-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 5. 連接池啓用Web監控統計功能start-->
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*. js ,*. gif ,*. jpg ,*. png ,*. css ,*. ico ,/ druid /*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!-- 連接池啓用Web監控統計功能end-->
</web-app>
database.properties
#druid配置
url:jdbc\:mysql\://localhost\:3306/quartz03?characterEncoding\=utf8&allowMultiQueries\=true
driverClassName:com.mysql.jdbc.Driver
username:root
password:admin
filters:stat
maxActive:20
initialSize:1
maxWait:60000
minIdle:10
maxIdle:15
timeBetweenEvictionRunsMillis:60000
minEvictableIdleTimeMillis:300000
validationQuery:SELECT 'x'
testWhileIdle:true
testOnBorrow:false
testOnReturn:false
maxOpenPreparedStatements:20
removeAbandoned:true
removeAbandonedTimeout:1800
logAbandoned:true
步驟3:前端頁面
前端頁面表格使用的bootstrap table,這裏不再累述,頁面樣式如下:
index.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2017/11/25 0020
Time: 下午 18:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="basePath" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
<title>定時任務</title>
<link rel="stylesheet" href="${basePath}/static/bootstrap-dist/css/bootstrap.min.css">
<link rel="stylesheet" href="${basePath}/static/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="${basePath}/static/css/bootstrap-table.min.css">
<script src="${basePath}/static/js/jquery-2.0.3.min.js"></script>
<script src="${basePath}/static/bootstrap-dist/js/bootstrap.min.js"></script>
<script src="${basePath}/static/js/bootstrap-table.min.js"></script>
<script src="${basePath}/static/js/bootstrap-table-zh-CN.js"></script>
</head>
<body>
<div id="rrapp" style="margin: 100px;">
<div id="showList">
<div class="grid-btn" style="height:34px;">
<a class="btn btn-primary" onclick="update();"><i class="fa fa-pencil-square-o"></i> 修改</a>
<a class="btn btn-primary" onclick="pause();"><i class="fa fa-pause"></i> 暫停</a>
<a class="btn btn-primary" onclick="resume();"><i class="fa fa-play"></i> 恢復</a>
<a class="btn btn-primary" onclick="runOnce();"><i class="fa fa-arrow-circle-right"></i> 立即執行</a>
</div>
<table id="table"></table>
</div>
<!-- 修改時間模態框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">修改定時任務時間</h4>
</div>
<div class="modal-body">
<input type="text" id="modalId" style="display:none"/>
Cron表達式
<input type="text" class="form-control" id="modalCron">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="updateCron();">Save changes</button>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
//初始化表格
initTable();
});
//修改按鈕
function update() {
//獲取選中的行
var a = $("#table").bootstrapTable('getSelections');
if (a.length == 0) {
alert("請先選中需要修改的項");
return false;
} else if (a.length > 1) {
alert("只能選擇一項");
return false;
}
$("#modalId").val(a[0].id);
$('#myModal').modal('toggle');
}
//更新定時任務時間
function updateCron() {
$('#myModal').modal('hide');
var id = $("#modalId").val();
var queryUrl = "${basePath}/scheduleJob/updateCron.do";
$.ajax({
type: 'POST',
data: {
id: id,
cronExpression: $("#modalCron").val(),
},
url: queryUrl,
success: function (result) {
//刷新表格
var opt = {
url: '${basePath}/scheduleJob/listAllJob.do'
};
$("#table").bootstrapTable('refresh', opt);
}
})
}
//暫停一個定時任務
function pause() {
var queryUrl = '${basePath}/scheduleJob/pauseJob.do';
commonSubmit(queryUrl);
}
//恢復一個定時任務
function resume() {
var queryUrl = '${basePath}/scheduleJob/resumeJob.do';
commonSubmit(queryUrl);
}
//立即執行一個定時任務
function runOnce() {
var queryUrl = "${basePath}/scheduleJob/runOnce.do";
commonSubmit(queryUrl);
}
//暫停、恢復、立即執行提交函數
function commonSubmit(queryUrl) {
//獲取選中的行
var a = $("#table").bootstrapTable('getSelections');
if (a.length == 0) {
alert("請先選中需要修改的項");
return false;
} else if (a.length > 1) {
alert("只能選擇一項");
return false;
}
var obj = a[0];
$.ajax({
type: 'post',
data: {
jobId: obj.id
},
url: queryUrl,
success: function (result) {
//刷新表格,狀態變更
var opt = {
url: '${basePath}/scheduleJob/listAllJob.do'
};
$("#table").bootstrapTable('refresh', opt);
}
});
}
//表格詳情
function initTable() {
var queryUrl = '${basePath}/scheduleJob/listAllJob.do';
$('#table').bootstrapTable({
method: 'POST',//請求方式(*)
contentType: "application/x-www-form-urlencoded;charset=UTF-8",//在服務端分頁時必須配置
dataType: 'json',
//toolbar: '#toolbar',//工具按鈕用哪個容器
striped: true,//是否顯示行間隔色
cache: false,//是否使用緩存,默認爲true,所以一般情況下需要設置一下這個屬性(*)
pagination: true,//是否顯示分頁(*)、
onlyInfoPagination: false,//設置爲true時只顯示總數據,而不顯示分頁按鈕
showPaginationSwitch: false,
sortable: true,//是否啓用排序
sortOrder: "asc",//排序方式
sidePagination: "server",//分頁方式:client客戶端分頁,server服務端分頁(*)
pageNumber: 1,//初始化加載第一頁,默認第一頁,並記錄
pageSize: 10,//每頁的記錄行數(*)
pageList: [10, 25, 50, 100],//可供選擇的每頁的行數(*)
url: queryUrl,//請求後臺的URL(*)
search: false,//是否顯示錶格搜索
strictSearch: true,
showColumns: false,//是否顯示所有的列(選擇顯示的列)
showRefresh: false,//是否顯示刷新按鈕
minimumCountColumns: 1,//最少允許的列數
clickToSelect: true,//是否啓用點擊選中行
//height: 500, //行高,如果沒有設置height屬性,表格自動根據記錄條數覺得表格高度
uniqueId: "ID",//每一行的唯一標識,一般爲主鍵列
showToggle: false, //是否顯示詳細視圖和列表視圖的切換按鈕
cardView: false,//是否顯示詳細視圖
detailView: false,//是否顯示父子表
paginationDetailHAlign: "left",//設置頁面條數信息位置,默認在左邊
showExport: false, //是否顯示導出
exportDataType: "selected", //basic', 'all', 'selected'.
//獲取查詢參數
queryParams: function queryParams(params) {
//這裏的鍵的名字和控制器的變量名必須一致,這邊改動,控制器也需要改成一樣的
var param = {
pageSize: params.limit, //頁面大小
pageNumber: (params.offset / params.limit) + 1, //頁碼
menuName: $("#menuNameQuery").val(), //菜單名稱
parentName: $("#parentNameQuery").val(),//上級菜單名稱
};
return param;
},
columns: [
{
field: 'Number',
title: '',
align: 'center',
width: 20,
formatter: function (value, row, index) {
return index + 1;
}
},
{
checkbox: true,
visible: true //是否顯示覆選框
}, {
field: 'id',
title: '任務ID',
width: 50,
align: 'center'
}, {
field: 'jobName',
title: 'JobName',
width: 150,
align: 'center'
}, {
field: 'jobGroup',
title: 'JobGroup',
width: 50,
align: 'center'
}, {
field: 'beanClass',
title: 'BeanClass',
align: 'center'
}, {
field: 'methodName',
title: 'MethodName',
width: 100,
align: 'center'
}, {
field: 'params',
title: '參數',
width: 100,
align: 'center'
}, {
field: 'cronExpression',
title: 'cron表達式',
width: 100,
align: 'center'
}, {
field: 'status',
title: '狀態',
width: 50,
align: 'center',
formatter: function (value, row, index) {
if (value == 0) {
return "<a href='javascript:void(0);' class='btn btn-primary btn-xs'>正常</a>";
}
if (value == 1) {
return "<a href='javascript:void(0);' class='btn btn-danger btn-xs'>暫停</a>";
}
}
}, {
field: 'remark',
title: '備註',
width: 100,
align: 'center'
}],
});
}
</script>
</body>
</html>
步驟4:定時任務的啓動、暫停、時間修改、立即執行
在數據庫中我們有設計字段status表示定時任務的狀態,0表示正常狀態,1表示暫停狀態
啓動服務器時需要啓動status爲1的定時任務
4.1 項目啓動時啓動定時任務
在service在中添加初始化方法,在方法前添加@PostConstruct註解。在方法裏面添加調用定時任務的方法
被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器調用一次,類似於Serclet的init()方法
4.2 定時任務的時間修改、暫停、立即執行
定時任務的修改、暫停主要是調用quartz內置方法pauseJob()、resumeJob()、triggerJob()等方法
//暫停一個job
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);
// 恢復一個定時任務
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
// 立即執行一個定時任務
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
// 更新時間表達式
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder =
CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = trigger.getTriggerBuilder()
.withIdentity(triggerKey)
.build();
scheduler.rescheduleJob(triggerKey,trigger);
ScheduleJobServiceImpl
package com.demo.service.impl;
import com.demo.common.result.BootstrapTableResult;
import com.demo.common.result.Constant;
import com.demo.dao.ScheduleJobMapper;
import com.demo.domain.ScheduleJob;
import com.demo.schedule.QuartzJobFactory;
import com.demo.service.ScheduleJobService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
/**
* @author Administrator
* @date 2017-11-21 上午 9:36
*/
@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {
private Logger log = LoggerFactory.getLogger(ScheduleJobServiceImpl.class);
@Resource
private ScheduleJobMapper scheduleJobMapper;
@Resource
private Scheduler scheduler;
public Scheduler getScheduler() {
return scheduler;
}
public void setScheduler(Scheduler scheduler) {
this.scheduler = scheduler;
}
/**
* 項目啓動時初始化定時器
*/
@PostConstruct
public void init() {
//獲取所有的定時任務
List<ScheduleJob> scheduleJobList = scheduleJobMapper.listAllJob();
if (scheduleJobList.size() != 0) {
for (ScheduleJob scheduleJob : scheduleJobList) {
addJob(scheduleJob);
}
}
}
/**
* 添加任務
* @param job
*/
private void addJob(ScheduleJob job) {
try {
log.info("初始化");
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//不存在,則創建
if (null == trigger) {
Class clazz = QuartzJobFactory.class;
JobDetail jobDetail = JobBuilder.
newJob(clazz).
withIdentity(job.getJobName(), job.getJobGroup()).
build();
jobDetail.getJobDataMap().put("scheduleJob", job);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
//withIdentity中寫jobName和groupName
trigger = TriggerBuilder.
newTrigger().
withIdentity(job.getJobName(), job.getJobGroup())
.withSchedule(scheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, trigger);
//如果定時任務是暫停狀態
if(job.getStatus() == Constant.STATUS_NOT_RUNNING){
pauseJob(job.getId());
}
} else {
// Trigger已存在,那麼更新相應的定時設置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表達式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新設置job執行
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
log.error("添加任務失敗", e);
}
}
/**
* 查詢所有的定時任務
* @return BootstrapTableResult
*/
@Override
public BootstrapTableResult listAllJob(int pageSize, int pageNumber) {
PageHelper.startPage(pageNumber, pageSize);
List<ScheduleJob> scheduleJobList = scheduleJobMapper.listAllJob();
PageInfo pageInfo = new PageInfo(scheduleJobList, Constant.PAGENUMBER);
int total = (int) pageInfo.getTotal();
BootstrapTableResult bootstrapTableResult = new BootstrapTableResult(total, scheduleJobList);
return bootstrapTableResult;
}
/**
* 暫停定時任務
* @param jobId
*/
@Override
public void pauseJob(int jobId) {
//修改定時任務狀態
ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);
scheduleJob.setId(jobId);
scheduleJob.setStatus(Constant.STATUS_NOT_RUNNING);
updateJobStatusById(scheduleJob);
try {
//暫停一個job
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);
}catch (Exception e){
log.error("CatchException:暫停任務失敗",e);
}
}
/**
* 恢復一個定時任務
* @param jobId
*/
@Override
public void resumeJob(int jobId) {
//修改定時任務狀態
ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);
scheduleJob.setStatus(Constant.STATUS_RUNNING);
updateJobStatusById(scheduleJob);
try{
//恢復一個定時任務
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
}catch (Exception e){
log.error("CatchException:恢復定時任務失敗",e);
}
}
/**
* 立即執行一個定時任務
* @param jobId
*/
@Override
public void runOnce(int jobId) {
try{
ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(jobId);
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
}catch (Exception e){
log.error("CatchException:恢復定時任務失敗",e);
}
}
/**
* 更新時間表達式
* @param id
* @param cronExpression
*/
@Override
public void updateCron(int id, String cronExpression) {
ScheduleJob scheduleJob = getScheduleJobByPrimaryKey(id);
scheduleJob.setCronExpression(cronExpression);
updateJobCronExpressionById(scheduleJob);
try {
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey,trigger);
}catch(Exception e){
log.error("CatchException:更新時間表達式失敗",e);
}
}
/**
* 修改定時任務狀態
* @param scheduleJob
*/
private void updateJobStatusById(ScheduleJob scheduleJob){
scheduleJobMapper.updateJobStatusById(scheduleJob);
}
/**
* 修改定時任務時間
*/
private void updateJobCronExpressionById(ScheduleJob scheduleJob){
scheduleJobMapper.updateJobCronExpressionById(scheduleJob);
}
/**
* 通過主鍵id查找定時任務
* @param id
* @return ScheduleJob
*/
private ScheduleJob getScheduleJobByPrimaryKey(int id){
return scheduleJobMapper.getScheduleJobByPrimaryKey(id);
}
}
QuartzJobFactory.java
package com.demo.schedule;
import com.demo.common.utils.TaskUtils;
import com.demo.domain.ScheduleJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author admin
* @date 2017-11-25 下午 21:49
*/
public class QuartzJobFactory implements Job {
public Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定時任務運行中...");
ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokeMethod(scheduleJob);
}
}
執行計劃任務的代碼就在TaskUtils.invokMethod(scheduleJob)裏面,通過scheduleJob的beanClass來獲得需要執行的類,通過methodName來確定執行哪個方法
定時任務啓動後,可以直接修改啓動、暫停狀態,但是重啓服務器時並不會記錄當前狀態,建議先將修改後的狀態保存到數據庫status字段中
TaskUtils.java
package com.demo.common.utils;
import com.demo.domain.ScheduleJob;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author admin
* @date 2017-11-21 下午 16:07
*/
public class TaskUtils {
public static Logger log = LoggerFactory.getLogger(TaskUtils.class);
public static void invokeMethod(ScheduleJob scheduleJob) {
Object object = null;
Class clazz = null;
if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
try {
clazz = Class.forName(scheduleJob.getBeanClass());
object = clazz.newInstance();
} catch (Exception e) {
log.error("CatchException:",e);
}
}
if (object == null) {
log.error("任務名稱 = [" + scheduleJob.getJobName() + "]---------------未啓動成功,請檢查是否配置正確!!!");
System.out.println("任務名稱 = [" + scheduleJob.getJobName() + "]---------------未啓動成功,請檢查是否配置正確!!!");
return;
}
clazz = object.getClass();
Method method = null;
try {
method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
} catch (NoSuchMethodException e) {
log.error("任務名稱 = [" + scheduleJob.getJobName() + "]---------------未啓動成功,方法名設置錯誤!!!");
System.out.println("任務名稱 = [" + scheduleJob.getJobName() + "]---------------未啓動成功,方法名設置錯誤!!!");
} catch (SecurityException e) {
e.printStackTrace();
}
if (method != null) {
try {
method.invoke(object);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
log.info("任務名稱 = [" + scheduleJob.getJobName() + "]----------啓動成功");
}
}
SpringContextUtil.java
package com.demo.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* 獲取spring容器,以訪問容器中定義的其他bean
* @author Administrator
* @date 2017-11-21 下午 12:39
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
/**
* Spring應用上下文環境
*/
public static ApplicationContext applicationContext;
/**
* 實現ApplicationContextAware接口的回調方法,設置上下文環境
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtils.applicationContext = applicationContext;
}
/**
* 獲取對象 這裏重寫了bean方法,起主要作用
* @param name
* @return Object 一個以所給名字註冊的bean的實例
* @throws BeansException
*/
public static <T> T getBean(String name) throws BeansException {
return (T) applicationContext.getBean(name);
}
/**
* 如果BeanFactory包含一個與所給名稱匹配的bean定義,則返回true
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
/**
* 判斷以給定名字註冊的bean定義是一個singleton還是一個prototype。
* 如果與給定名字相應的bean定義沒有被找到,將會拋出一個異常(NoSuchBeanDefinitionException)
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
/**
* @param name
* @return Class 註冊對象的類型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static Class<? extends Object> getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
4.3 需要執行的定時任務
TaskTest1.java
package com.demo.schedule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
import java.util.Map;
/**
* @author admin
* @date 2017-11-25 下午 20:14
*/
@Component
public class TaskTest1 {
public static final Logger LOGGER = LoggerFactory.getLogger(TaskTest1.class);
public void run1(){
System.out.println("執行方法1");
}
public void run2(){
System.out.println("執行方法2");
}
public void run3(){
System.out.println("執行方法3");
}
public void run4(){
System.out.println("執行方法4");
}
}
4.4 項目中涉及到的其他文件
Constant.java
/**
* 常量類
* @author admin
* @date 2017-11-25 19:06
*/
public class Constant {
/**
* 分頁條顯示頁數
*/
public static final int PAGENUMBER = 5;
/**
* 定時任務啓動狀態
*/
public static final int STATUS_RUNNING = 0;
/**
* 定時任務暫停狀態
*/
public static final int STATUS_NOT_RUNNING = 1;
}
BootstrapTableResult.java
/**
* bootstrapTable所需的結果集
* @author admin
* @date 2017-11-25 18:59
*/
public class BootstrapTableResult {
/**
* 總記錄數
*/
private Integer total;
/**
* 結果集的list集合
*/
private List rows;
省略get/set...
}
BaseResult.java
/**
* 統一返回結果類
* @author Administrator
* @date 2017-11-25 下午 20:07
*/
public class BaseResult {
/**
* 狀態碼:1成功,其他爲失敗
*/
private int code;
/**
* 成功爲success,其他爲失敗原因
*/
private String message;
/**
* 數據結果集
*/
public Object data;
省略get/set
ScheduleJob實體類
/**
* 定時任務實體類
* @author admin
* @date 2017-11-25 下午 19:06
*/
public class ScheduleJob {
/**
* 主鍵id
*/
private Integer id;
/**
* 任務名
*/
private String jobName;
/**
* 任務組
*/
private String jobGroup;
/**
* 要執行的方法的名稱
*/
private String methodName;
/**
* 要執行的方法所在的class路徑
*/
private String beanClass;
/**
* 定時任務狀態,0表示正常,1表示停止
*/
private Integer status;
/**
* 時間表達式
*/
private String cronExpression;
/**
* 參數
*/
private String params;
/**
* 備註
*/
private String remark;
/**
* 創建時間
*/
private Date createTime;
/**
* 修改時間
*/
private Date modifyTime;
省略get/set
}
Controller層:ScheduleJobController.java
package com.demo.controller;
import com.demo.common.result.BaseResult;
import com.demo.common.result.BootstrapTableResult;
import com.demo.service.ScheduleJobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* 定時任務控制層
* @author admin
* @date 2017-11-25 18:49
*/
@Controller
@RequestMapping(value = "/scheduleJob")
public class ScheduleJobController {
public static Logger log = LoggerFactory.getLogger(ScheduleJobController.class);
@Resource
private ScheduleJobService scheduleJobService;
/**
* 查詢所有的定時任務,用於頁面加載時顯示錶格數據
* @param pageSize 每頁顯示數量
* @param pageNumber 頁數
* @return BootstrapTableResult
*/
@RequestMapping(value = "/listAllJob", method = RequestMethod.POST)
@ResponseBody
public BootstrapTableResult listAllJob(int pageSize, int pageNumber) {
BootstrapTableResult bootstrapTableResult = scheduleJobService.listAllJob(pageSize, pageNumber);
return bootstrapTableResult;
}
/**
* 暫停定時任務
* @param jobId
* @return BaseResult
*/
@RequestMapping(value = "/pauseJob", method = RequestMethod.POST)
@ResponseBody
public BaseResult pauseJob(int jobId) {
scheduleJobService.pauseJob(jobId);
return new BaseResult(1, "success", "定時任務暫停成功");
}
/**
* 恢復定時任務
* @param jobId
* @return BaseResult
*/
@RequestMapping(value="/resumeJob",method = RequestMethod.POST)
@ResponseBody
public BaseResult resumeJob(int jobId){
scheduleJobService.resumeJob(jobId);
return new BaseResult(1, "success", "定時任務恢復成功");
}
/**
* 立即執行定時任務
* @param jobId
* @return BaseResult
*/
@RequestMapping(value = "/runOnce",method = RequestMethod.POST)
@ResponseBody
public BaseResult runOnce(int jobId){
scheduleJobService.runOnce(jobId);
return new BaseResult(1, "success", "立即執行定時任務成功");
}
/**
* 更新時間表達式
* @param id
* @param cronExpression
* @return BaseResult
*/
@RequestMapping(value = "/updateCron",method = RequestMethod.POST)
@ResponseBody
public BaseResult updateCron(int id,String cronExpression){
scheduleJobService.updateCron(id,cronExpression);
return new BaseResult(1, "success", "更新時間表達式成功");
}
}
dao層:ScheduleJobMapper.java
package com.demo.dao;
import com.demo.domain.ScheduleJob;
import java.util.List;
/**
* 定時任務
* @author admin
* @date 2017-11-20 下午 15:52
*/
public interface ScheduleJobMapper {
/**
* 查詢所有的定時任務
* @return List<ScheduleJob>
*/
List<ScheduleJob> listAllJob();
/**
* 更新定時任務狀態
* @param scheduleJob
*/
void updateJobStatusById(ScheduleJob scheduleJob);
/**
* 根據主鍵查詢定時任務
* @param id
* @return ScheduleJob
*/
ScheduleJob getScheduleJobByPrimaryKey(int id);
/**
* 更新時間表達式
* @param scheduleJob
*/
void updateJobCronExpressionById(ScheduleJob scheduleJob);
}
dao實現層:ScheduleJobMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.dao.ScheduleJobMapper">
<resultMap id="BaseResultMap" type="com.demo.domain.ScheduleJob">
<id column="id" property="id" />
<result column="job_name" property="jobName" />
<result column="job_group" property="jobGroup" />
<result column="method_name" property="methodName" />
<result column="bean_class" property="beanClass" />
<result column="status" property="status" />
<result column="cron_expression" property="cronExpression" />
<result column="params" property="params" />
<result column="remark" property="remark" />
<result column="create_time" property="createTime" />
<result column="modify_time" property="modifyTime" />
</resultMap>
<sql id="Base_Column_List">
id, job_name, job_group, method_name, bean_class, status, cron_expression, params,
remark, create_time, modify_time
</sql>
<!-- 查詢所有的定時任務 -->
<select id="listAllJob" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from schedule_job
</select>
<!-- 更新定時任務狀態 -->
<update id="updateJobStatusById" parameterType="ScheduleJob">
update schedule_job SET status = #{status} where id = #{id}
</update>
<!-- 根據主鍵查詢定時任務 -->
<select id = "getScheduleJobByPrimaryKey" resultMap="BaseResultMap">
SELECT * from schedule_job WHERE id = #{id}
</select>
<!-- 修改定時任務時間表達式 -->
<update id="updateJobCronExpressionById" parameterType="ScheduleJob">
UPDATE schedule_job SET cron_expression = #{cronExpression} where id = #{id}
</update>
</mapper>
service層:ScheduleJobService.java
package com.demo.service;
import com.demo.common.result.BootstrapTableResult;
import com.demo.dao.ScheduleJobMapper;
import org.quartz.Scheduler;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author admin
* @date 2017-11-25 18:51
*/
public interface ScheduleJobService {
/**
* 查詢所有的定時任務
* @param pageSize
* @param pageNumber
* @return BootstrapTableResult
*/
BootstrapTableResult listAllJob(int pageSize, int pageNumber);
/**
* 暫停定時任務
* @param jobId
*/
void pauseJob(int jobId);
/**
* 恢復一個定時任務
* @param jobId
*/
void resumeJob(int jobId);
/**
* 立即執行一個定時任務
* @param jobId
*/
void runOnce(int jobId);
/**
* 更新時間表達式
* @param id
* @param cronExpression
*/
void updateCron(int id, String cronExpression);
}
步驟5. 測試
在數據庫中添加以下數據
第一條每5秒執行一次,第二條數據每秒執行一次,第三條和第四條數據啓動時不執行
啓動服務器,控制檯輸出如下結果
修改定時任務1的時間,設置爲5秒,查看控制檯,可以看到定時任務1和定時任務2都是每5秒執行一次
暫定、恢復、立即執行這裏就不一一測試了,有需要的自行測試(注:立即執行只會執行一次)