前端基于Bootstrap的輕量級表格插件 Bootstrap Table
后端分頁組件使用Mybatis分頁插件 PageHelper
分頁實(shí)現(xiàn)流程
1、前端調(diào)用封裝好的方法$.table.init,傳入后臺url。
var options = {
url: prefix + "/list",
columns: [{
field: 'id',
title: '主鍵'
},
{
field: 'name',
title: '名稱'
}]
};
$.table.init(options);
2、后臺實(shí)現(xiàn)查詢邏輯,調(diào)用startPage()方法即可自動完成服務(wù)端分頁。
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(User user)
{
startPage(); // 此方法配合前端完成自動分頁
List<User> list = userService.selectUserList(user);
return getDataTable(list);
}
注意:啟動分頁關(guān)鍵代碼startPage()
(只對該語句以后的第一個查詢語句得到的數(shù)據(jù)進(jìn)行分頁)
如果改為其他數(shù)據(jù)庫需修改配置application.yml
helperDialect=你的數(shù)據(jù)庫
導(dǎo)入導(dǎo)出使用 Apache POI
,目前支持參數(shù)如下
參數(shù) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
name | String | 空 | 導(dǎo)出到Excel中的名字 |
dateFormat | String | 空 | 日期格式, 如: yyyy-MM-dd |
readConverterExp | String | 空 | 讀取內(nèi)容轉(zhuǎn)表達(dá)式 (如: 0=男,1=女,2=未知) |
height | String | 14 | 導(dǎo)出時在excel中每個列的高度 單位為字符 |
width | String | 16 | 導(dǎo)出時在excel中每個列的寬 單位為字符 |
suffix | String | 空 | 文字后綴,如% 90 變成90% |
defaultValue | String | 空 | 當(dāng)值為空時,字段的默認(rèn)值 |
prompt | String | 空 | 提示信息 |
combo | String | Null | 設(shè)置只能選擇不能輸入的列內(nèi)容 |
isExport | String | true | 是否導(dǎo)出數(shù)據(jù),應(yīng)對需求:有時我們需要導(dǎo)出一份模板,這是標(biāo)題需要但內(nèi)容需要用戶手工填寫 |
targetAttr | String | 空 | 另一個類中的屬性名稱,支持多級獲取,以小數(shù)點(diǎn)隔開 |
type | Enum | Type.ALL | 字段類型(0:導(dǎo)出導(dǎo)入;1:僅導(dǎo)出;2:僅導(dǎo)入) |
導(dǎo)出實(shí)現(xiàn)流程
1、前端調(diào)用封裝好的方法$.table.init,傳入后臺exportUrl。
var options = {
exportUrl: prefix + "/export",
columns: [{
field: 'id',
title: '主鍵'
},
{
field: 'name',
title: '名稱'
}]
};
$.table.init(options);
2、在實(shí)體變量上添加@Excel注解。
@Excel(name = "用戶序號")
private Long id;
@Excel(name = "用戶名稱")
private String userName;
3、在Controller添加導(dǎo)出方法
@PostMapping("/export")
@ResponseBody
public AjaxResult export(User user)
{
List<User> list = userService.selectUserList(user);
ExcelUtil<User> util = new ExcelUtil<User>(User.class);
return util.exportExcel(list, "用戶數(shù)據(jù)");
}
導(dǎo)入實(shí)現(xiàn)流程
1、前端調(diào)用封裝好的方法$.table.init,傳入后臺importUrl。
var options = {
importUrl: prefix + "/importData",
columns: [{
field: 'id',
title: '主鍵'
},
{
field: 'name',
title: '名稱'
}]
};
$.table.init(options);
2、在實(shí)體變量上添加@Excel注解,默認(rèn)為導(dǎo)出導(dǎo)入,也可以單獨(dú)設(shè)置僅導(dǎo)入Type.IMPORT
@Excel(name = "用戶序號")
private Long id;
@Excel(name = "部門編號", type = Type.IMPORT)
private Long deptId;
@Excel(name = "用戶名稱")
private String userName;
3、在Controller添加導(dǎo)入方法,updateSupport屬性為是否存在則覆蓋(可選)
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = ShiroUtils.getSysUser().getLoginName();
String message = userService.importUser(userList, updateSupport, operName);
return AjaxResult.success(message);
}
首先創(chuàng)建一張上傳文件的表,例如:
drop table if exists sys_file;
create table sys_file (
fileid int(11) not null auto_increment comment '文件id',
filename varchar(50) default '' comment '文件名稱',
filepath varchar(255) default '' comment '文件路徑',
primary key (fileid)
) engine=innodb auto_increment=200 default charset=utf8 comment = '文件表';
上傳實(shí)現(xiàn)流程
1、參考示例代碼。
function submitHandler() {
if ($.validate.form()) {
uploadFile();
}
}
function uploadFile() {
var formData = new FormData();
if($('#file')[0].files[0] == null) {
$.modal.alertWarning("請先選擇文件路徑");
return false;
}
formData.append('fileName', $("#fileName").val());
formData.append('file', $('#file')[0].files[0]);
$.ajax({
url: prefix + "/add",
type: 'post',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(result) {
$.operate.successCallback(result);
}
});
}
2、在Controller添加對應(yīng)上傳方法
@Autowired
private ServerConfig serverConfig;
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(MultipartFile file, SysFile sysFile) throws IOException
{
// 上傳文件路徑
String filePath = Global.getUploadPath();
// 上傳并返回新文件名稱
String fileName = FileUploadUtils.upload(filePath, file);
sysFile.setFilePath(fileName);
return toAjax(sysFileService.insertSysFile(sysFile));
}
3、上傳成功后需要預(yù)覽可以對該屬性格式化處理
{
title: '文件預(yù)覽',
formatter: function(value, row, index) {
return '<a href="javascript:downloadFile(' + row.fileId + ')"><img style="width:30;height:30px;" src="/profile/upload/' + row.filePath + '"/></a>';
}
},
注意:如果只是單純的上傳一張圖片沒有其他參數(shù)可以使用通用方法 /common/upload
請求處理方法 com.ruoyi.web.controller.common.CommonController
下載實(shí)現(xiàn)流程
1、參考示例代碼。
function downloadFile(fileId){
window.location.href = ctx + "system/sysFile/downloadFile/" + fileId;
}
2、在Controller添加對應(yīng)上傳方法
@GetMapping("/downloadFile/{fileId}")
public void downloadFile(@PathVariable("fileId") Integer fileId, HttpServletResponse response) throws Exception
{
SysFile sysFile = sysFileService.selectSysFileById(fileId);
String filePath = sysFile.getFilePath();
String realFileName = sysFile.getFileName() + filePath.substring(filePath.indexOf("."));
String path = Global.getUploadPath() + sysFile.getFilePath();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + realFileName);
FileUtils.writeBytes(path, response.getOutputStream());
}
在Spring Boot中,當(dāng)我們使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依賴的時候,框架會自動默認(rèn)分別注入DataSourceTransactionManager或JpaTransactionManager。 所以我們不需要任何額外配置就可以用@Transactional注解進(jìn)行事務(wù)的使用。
例如:新增用戶時需要插入用戶表、用戶與崗位關(guān)聯(lián)表、用戶與角色關(guān)聯(lián)表。就可以使用事務(wù)讓它實(shí)現(xiàn)回退。
做法非常簡單,我們只需要在方法上添加@Transactional注解即可。事務(wù)可以用于Service
和Controller
@Transactional
public int insertUser(User user)
{
// 新增用戶信息
int rows = userMapper.insertUser(user);
// 新增用戶崗位關(guān)聯(lián)
insertUserPost(user);
// 新增用戶與角色管理
insertUserRole(user);
return rows;
}
常見坑點(diǎn)1:遇到非檢測異常時,事務(wù)開啟,也無法回滾。 例如下面這段代碼,賬戶余額依舊增加成功,并沒有因?yàn)楹竺嬗龅綑z測異常而回滾?。?/p>
@Transactional
public void addMoney() throws Exception {
//先增加余額
accountMapper.addMoney();
//然后遇到故障
throw new SQLException("發(fā)生異常了..");
}
原因分析:因?yàn)镾pring的默認(rèn)的事務(wù)規(guī)則是遇到運(yùn)行異常(RuntimeException)和程序錯誤(Error)才會回滾。如果想針對非檢測異常進(jìn)行事務(wù)回滾,可以在@Transactional 注解里使用 rollbackFor 屬性明確指定異常。例如下面這樣,就可以正?;貪L:
@Transactional(rollbackFor = Exception.class)
public void addMoney() throws Exception {
//先增加余額
accountMapper.addMoney();
//然后遇到故障
throw new SQLException("發(fā)生異常了..");
}
常見坑點(diǎn)2: 在業(yè)務(wù)層捕捉異常后,發(fā)現(xiàn)事務(wù)不生效。 這是許多新手都會犯的一個錯誤,在業(yè)務(wù)層手工捕捉并處理了異常,你都把異?!俺浴钡袅耍琒pring自然不知道這里有錯,更不會主動去回滾數(shù)據(jù)。 例如:下面這段代碼直接導(dǎo)致增加余額的事務(wù)回滾沒有生效。
@Transactional
public void addMoney() throws Exception {
//先增加余額
accountMapper.addMoney();
//謹(jǐn)慎:盡量不要在業(yè)務(wù)層捕捉異常并處理
try {
throw new SQLException("發(fā)生異常了..");
} catch (Exception e) {
e.printStackTrace();
}
}
推薦做法:在業(yè)務(wù)層統(tǒng)一拋出異常,然后在控制層統(tǒng)一處理。
@Transactional
public void addMoney() throws Exception {
//先增加余額
accountMapper.addMoney();
//推薦:在業(yè)務(wù)層將異常拋出
throw new RuntimeException("發(fā)生異常了..");
}
Transactional注解的常用屬性表:
屬性 | 說明 |
---|---|
propagation | 事務(wù)的傳播行為,默認(rèn)值為 REQUIRED。 |
isolation | 事務(wù)的隔離度,默認(rèn)值采用 DEFAULT |
timeout | 事務(wù)的超時時間,默認(rèn)值為-1,不超時。如果設(shè)置了超時時間(單位秒),那么如果超過該時間限制了但事務(wù)還沒有完成,則自動回滾事務(wù)。 |
read-only | 指定事務(wù)是否為只讀事務(wù),默認(rèn)值為 false;為了忽略那些不需要事務(wù)的方法,比如讀取數(shù)據(jù),可以設(shè)置 read-only 為 true。 |
rollbackFor | 用于指定能夠觸發(fā)事務(wù)回滾的異常類型,如果有多個異常類型需要指定,各類型之間可以通過逗號分隔。{xxx1.class, xxx2.class,……} |
noRollbackFor | 拋出 no-rollback-for 指定的異常類型,不回滾事務(wù)。{xxx1.class, xxx2.class,……} |
.... |
TransactionDefinition傳播行為的常量:
常量 | 含義 |
---|---|
TransactionDefinition.PROPAGATION_REQUIRED | 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則創(chuàng)建一個新的事務(wù)。這是默認(rèn)值。 |
TransactionDefinition.PROPAGATION_REQUIRES_NEW | 創(chuàng)建一個新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。 |
TransactionDefinition.PROPAGATION_SUPPORTS | 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。 |
TransactionDefinition.PROPAGATION_NOT_SUPPORTED | 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。 |
TransactionDefinition.PROPAGATION_NEVER | 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。 |
TransactionDefinition.PROPAGATION_MANDATORY | 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則拋出異常。 |
TransactionDefinition.PROPAGATION_NESTED | 如果當(dāng)前存在事務(wù),則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運(yùn)行;如果當(dāng)前沒有事務(wù),則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED。 |
提示:事務(wù)的傳播機(jī)制是指如果在開始當(dāng)前事務(wù)之前,一個事務(wù)上下文已經(jīng)存在,此時有若干選項(xiàng)可以指定一個事務(wù)性方法的執(zhí)行行為。 即:在執(zhí)行一個@Transactinal注解標(biāo)注的方法時,開啟了事務(wù);當(dāng)該方法還在執(zhí)行中時,另一個人也觸發(fā)了該方法;那么此時怎么算事務(wù)呢,這時就可以通過事務(wù)的傳播機(jī)制來指定處理方式。
在日常開發(fā)中程序發(fā)生了異常,往往需要通過一個統(tǒng)一的異常處理,來保證客戶端能夠收到友好的提示。
通常情況下我們用try..catch..對異常進(jìn)行捕捉處理,但是在實(shí)際項(xiàng)目中對業(yè)務(wù)模塊進(jìn)行異常捕捉,會造成代碼重復(fù)和繁雜,
我們希望代碼中只有業(yè)務(wù)相關(guān)的操作,所有的異常我們單獨(dú)設(shè)立一個類來處理它。全局異常就是對框架所有異常進(jìn)行統(tǒng)一管理
而這就表示在框架需要一個機(jī)制,將程序的異常轉(zhuǎn)換為用戶可讀的異常。而且最重要的,是要將這個機(jī)制統(tǒng)一,提供統(tǒng)一的異常處理。
我們在可能發(fā)生異常的方法,全部throw拋給前端控制器;然后由前端控制器調(diào)用 全局異常處理器 對異常進(jìn)行統(tǒng)一處理。
如此,我們現(xiàn)在的Controller中的方法就可以很簡潔了。
1、統(tǒng)一返回實(shí)體定義
package com.ruoyi.common.core.domain;
import java.util.HashMap;
/**
* 操作消息提醒
*
* @author ruoyi
*/
public class AjaxResult extends HashMap<String, Object>
{
private static final long serialVersionUID = 1L;
/**
* 返回錯誤消息
*
* @param code 錯誤碼
* @param msg 內(nèi)容
* @return 錯誤消息
*/
public static AjaxResult error(String msg)
{
AjaxResult json = new AjaxResult();
json.put("msg", msg);
json.put("code", 500);
return json;
}
/**
* 返回成功消息
*
* @param msg 內(nèi)容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
AjaxResult json = new AjaxResult();
json.put("msg", msg);
json.put("code", 0);
return json;
}
}
2、定義登錄異常定義
package com.ruoyi.common.exception;
/**
* 登錄異常
*
* @author ruoyi
*/
public class LoginException extends RuntimeException
{
private static final long serialVersionUID = 1L;
protected final String message;
public LoginException(String message)
{
this.message = message;
}
@Override
public String getMessage()
{
return message;
}
}
3、基于@ControllerAdvice注解的Controller層的全局異常統(tǒng)一處理
package com.ruoyi.framework.web.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.LoginException;
/**
* 全局異常處理器
*
* @author ruoyi
*/
@RestControllerAdvice
public class GlobalExceptionHandler
{
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 登錄異常
*/
@ExceptionHandler(LoginException.class)
public AjaxResult loginException(LoginException e)
{
log.error(e.getMessage(), e);
return AjaxResult.error(e.getMessage());
}
}
4、測試訪問請求
@Controller
public class SysIndexController
{
/**
* 首頁方法
*/
@GetMapping("/index")
public String index(ModelMap mmap)
{
/**
* 模擬用戶未登錄,拋出業(yè)務(wù)邏輯異常
*/
SysUser user = ShiroUtils.getSysUser();
if (StringUtils.isNull(user))
{
throw new LoginException("用戶未登錄,無法訪問請求。");
}
mmap.put("user", user);
return "index";
}
}
根據(jù)上面代碼含義,當(dāng)我們在訪問/index時就會發(fā)生LoginException業(yè)務(wù)邏輯異常,按照我們之前的全局異常配置以及統(tǒng)一返回實(shí)體實(shí)例化,訪問后會出現(xiàn)AjaxResult格式JSON數(shù)據(jù),
下面我們運(yùn)行項(xiàng)目訪問查看效果。
界面輸出內(nèi)容如下所示:
{
"msg": "用戶未登錄,無法訪問請求。",
"code": 500
}
這個代碼示例寫的非常淺顯易懂,但是需要注意的是:基于@ControllerAdvice注解的全局異常統(tǒng)一處理只能針對于Controller層的異常,意思是只能捕獲到Controller層的異常, 在service層或者其他層面的異常都不能捕獲。
若依系統(tǒng)的全局異常處理器GlobalExceptionHandler
注意:如果全部異常處理返回json
,那么可以使用@RestControllerAdvice
代替@ControllerAdvice
,這樣在方法上就可以不需要添加@ResponseBody
。
在實(shí)際開發(fā)中,對于某些關(guān)鍵業(yè)務(wù),我們通常需要記錄該操作的內(nèi)容,一個操作調(diào)一次記錄方法,每次還得去收集參數(shù)等等,會造成大量代碼重復(fù)。 我們希望代碼中只有業(yè)務(wù)相關(guān)的操作,所有的異常我們單獨(dú)設(shè)立一個注解來處理它。
在需要被記錄日志的controller
方法上添加@Log注解,使用方法如下:
@Log(title = "用戶管理", businessType = BusinessType.INSERT)
支持參數(shù)如下:
參數(shù) | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
title | String | 空 | 操作模塊 |
businessType | BusinessType | BusinessType.OTHER | 操作功能 |
operatorType | OperatorType | OperatorType.MANAGE | 操作人類別 |
isSaveRequestData | boolean | true | 是否保存請求的參數(shù) |
邏輯實(shí)現(xiàn)代碼 com.ruoyi.framework.aspectj.LogAspect
查詢操作詳細(xì)記錄可以登錄系統(tǒng)(系統(tǒng)管理-操作日志)
在實(shí)際開發(fā)中,需要設(shè)置用戶只能查看哪些部門的數(shù)據(jù),一般稱為數(shù)據(jù)權(quán)限
默認(rèn)系統(tǒng)管理員admin
擁有所有數(shù)據(jù)權(quán)限(userId=1)
在需要數(shù)據(jù)權(quán)限控制方法上添加@DataScope注解
@DataScope(tableAlias = "u"),其中u
用來表示表的別名
/** 表的別名 */
String tableAlias() default "";
在mybatis查詢標(biāo)簽中添加數(shù)據(jù)范圍過濾 ${params.dataScope}
會生成如下關(guān)鍵代碼:
select u.user_id, u.dept_id, u.login_name, u.user_name, u.email , u.phonenumber,
u.password, u.sex, u.avatar, u.salt, u.status, u.del_flag, u.login_ip,
u.login_date, u.create_by, u.create_time, u.remark, d.dept_name
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
where u.del_flag = '0'
and u.dept_id in ( select dept_id from sys_role_dept where role_id = 2 )
邏輯實(shí)現(xiàn)代碼 com.ruoyi.framework.aspectj.DataScopeAspect
在實(shí)際開發(fā)中,經(jīng)常可能遇到在一個應(yīng)用中可能需要訪問多個數(shù)據(jù)庫的情況
在需要切換數(shù)據(jù)源Service
或Mapper
方法上添加@DataSource
注解
@DataSource(value = DataSourceType.MASTER),其中value
用來表示數(shù)據(jù)源名稱
/** 切換數(shù)據(jù)源名稱 */
public DataSourceType value() default DataSourceType.MASTER;
注解實(shí)現(xiàn)數(shù)據(jù)源切換
@DataSource(value = DataSourceType.MASTER)
public List<SysUser> selectUserList(SysUser user)
{
return userMapper.selectUserList(user);
}
手動實(shí)現(xiàn)數(shù)據(jù)源切換
public List<SysUser> selectUserList(SysUser user)
{
DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
List<SysUser> userList = userMapper.selectUserList(user);
DynamicDataSourceContextHolder.clearDataSourceType();
return userList;
}
邏輯實(shí)現(xiàn)代碼 com.ruoyi.framework.aspectj.DataSourceAspect
注意:目前配置了一個從庫,默認(rèn)關(guān)閉狀態(tài)??尚略龆鄠€從庫,支持不同數(shù)據(jù)源(Mysql、Oracle、SQLServer)
大部分項(xiàng)目里其實(shí)有很多代碼都是重復(fù)的,幾乎每個基礎(chǔ)模塊的代碼都有增刪改查的功能,而這些功能都是大同小異,如果這些功能都要自己去寫,將會大大浪費(fèi)我們的精力降低效率。所以這種重復(fù)性的代碼可以使用代碼生成。
1、修改代碼生成配置
編輯resources目錄下的generator.yml
author
: # 開發(fā)者姓名,生成到類注釋上
packageName
: # 默認(rèn)生成包路徑
autoRemovePre
: # 是否自動去除表前綴
tablePrefix
: # 表前綴
2、新建數(shù)據(jù)庫表結(jié)構(gòu)(需要表注釋)
drop table if exists sys_test;
create table sys_test (
test_id int(11) auto_increment comment '測試id',
test_name varchar(30) default '' comment '測試名稱',
primary key (test_id)
) engine=innodb auto_increment=1 default charset=utf8 comment = '測試表';
3、登錄系統(tǒng)-系統(tǒng)工具 -> 代碼生成
找到sys_test
表,點(diǎn)擊生成代碼會得到一個ruoyi.zip
執(zhí)行sql
文件,覆蓋文件到對應(yīng)目錄即可
所有代碼生成的相關(guān)業(yè)務(wù)邏輯代碼在ruoyi-generator
模塊,可以自行調(diào)整或剔除
在實(shí)際項(xiàng)目開發(fā)中,除了Web應(yīng)用、還有一類不可缺少的,那就是定時任務(wù)。 定時任務(wù)的場景可以說非常廣泛,比如某些視頻網(wǎng)站,購買會員后,每天會給會員送成長值,每月會給會員送一些電影券; 比如在保證最終一致性的場景中,往往利用定時任務(wù)調(diào)度進(jìn)行一些比對工作;比如一些定時需要生成的報表、郵件;比如一些需要定時清理數(shù)據(jù)的任務(wù)等。 所有我們提供方便友好的web界面,實(shí)現(xiàn)動態(tài)管理任務(wù),可以達(dá)到動態(tài)控制定時任務(wù)啟動、暫停、重啟、刪除、添加、修改等操作,極大地方便了開發(fā)過程。
1、新建定時任務(wù)信息(系統(tǒng)監(jiān)控 -> 定時任務(wù))
任務(wù)名稱:對應(yīng)后臺bean注解名稱,如@Component("ryTask")
任務(wù)組名:對應(yīng)的定時任務(wù)組名 隨意填寫。
方法名稱:對應(yīng)后臺任務(wù)方法名稱如ryParams
方法參數(shù):對應(yīng)后臺任務(wù)方法名稱值如ry
,沒有可不填。
執(zhí)行表達(dá)式:可查詢官方cron表達(dá)式介紹
執(zhí)行策略:
立即執(zhí)行(所有被misfire的執(zhí)行會被立即執(zhí)行,然后按照正常調(diào)度繼續(xù)執(zhí)行trigger。 9點(diǎn)和10點(diǎn)的被忽略掉,好像什么都沒發(fā)生一樣。下次執(zhí)行將在11點(diǎn)被執(zhí)行。)
執(zhí)行一次(立即執(zhí)行第一次misfire的操作,并且放棄其他misfire的(類似所有misfire的操作被合并執(zhí)行了)。然后繼續(xù)按調(diào)度執(zhí)行。無論misfire多少次trigger的執(zhí)行,都只會立刻執(zhí)行1次 9點(diǎn)和10點(diǎn)的被合并執(zhí)行一次(換句話說,10點(diǎn)需要執(zhí)行的那次,被pass了)。下次執(zhí)行將在11點(diǎn)被準(zhǔn)時執(zhí)行)
放棄執(zhí)行(所有被misfire的執(zhí)行都被忽略掉,調(diào)度器會像平時一樣等待下次調(diào)度 9點(diǎn)和10點(diǎn)的執(zhí)行(misfire的2個)被立即執(zhí)行,下次執(zhí)行將在11點(diǎn)被準(zhǔn)時執(zhí)行。)
并發(fā)執(zhí)行:是否需要多個任務(wù)間同時執(zhí)行
狀態(tài):是否啟動定時任務(wù)
備注:描述信息
2、點(diǎn)擊執(zhí)行一次,測試定時任務(wù)是否正常及調(diào)度日志是否正確記錄
所有定時任務(wù)的相關(guān)業(yè)務(wù)邏輯代碼在ruoyi-quartz
模塊,可以自行調(diào)整或剔除
注意:不同數(shù)據(jù)源定時任務(wù)都有對應(yīng)腳本,Oracle、Mysql已經(jīng)有了,其他的可自行下載執(zhí)行
更多建議: