1、 背景html
接上一篇隨筆,完成存儲過程的動態生成後,須要構建定時任務執行存儲過程java
2、 環境mysql
1.此隨筆內容基於spring boot項目spring
2.數據庫爲mysql 5.7.9版本sql
3.jdk 版本爲1.8數據庫
3、 說明app
略 ide
4、 內容ui
一、定義接口和接口參數bean;this
1)在上一篇博客bean 的基礎上把接口配置參數bean修改一下,添加一個配置參數值和排序字段;在添加一個監測項的bean,想查看其餘的bean信息,請移步: java Spring動態生成Mysql存儲過程
@Entity @Table(name="monitor_warn_item") public class MonitorWarnItem { @Id private String id; private String proName;//名稱 private String rule; private String send_content; private String recommend_value;// 建議值 private String standard_value; // 標準值 private Integer fre_num; private String frequency; private String status; private String warnType; private String warn_date_num;// 監測頻次 //此處省略get、set… } @Entity @Table(name="qt_interface_parameter") public class QtInterfaceParameter { @Id private String id; @Column(name="inter_id") private String interId; private String name; //參數名稱 private String explain_info; //參數描述 private String type;// 輸入輸出類型 private String paraType; // 參數類型 private Integer paraLen; private Integer paraValue; // 參數值 private Integer order_num; // 排序字段 //此處省略get、set… }
二、定義ScheduledFuture定時任務
1) 添加接口
public interface TestService { ResultInfo initMonitor(String Id);
// 省略以前的... }
2) 編寫實現類
@Service public class TestServiceImpl implements TestService { @Autowired private MonitorWarnItemRepository monitorWarnItemRepository @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { return new ThreadPoolTaskScheduler(); } List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>(); // 新建任務信息集合 /** * 初始化監測項 * * @param Id * @return */ @Override @Transactional public ResultInfo initMonitor(String Id) { ResultInfo info = new ResultInfo(); String msg = ""; MonitorWarnItem item = monitorWarnItemRepository.findId(Id); msg =buildTask(item); info.setResult(1); info.setMsg("初始化成功,初始化返回信息:" + msg); System.out.println(msg);// 日誌打印 return info; } /** * 配置任務信息 * * @param qt * @return */ private String buildTask(MonitorWarnItem qt) { String msg = ""; if (IsFure(qt.getId())) { List<QtInterface> InterList = qtInterfaceRepository.QueryInterFaceByItemId(qt.getId()); if (InterList.size() > 0) { Map<String, Object> map_future = new HashMap<>(); ScheduledFuture<?> future;// 監測任務 List<QtInterfaceParameter> para = qtInterfaceParameterRepository.QueryInfoByInterId(InterList.get(0).getId()); // 查找參數信息 List<String> map = new ArrayList<>(para.size()); if (para.size() > 0) { // 參數集合 for (QtInterfaceParameter pa : para) { for (int item = 1; item <= para.size(); item++) { if (item == pa.getOrder_num()) { // 根據字段排序來設置參數值的順序 map.add(pa.getPara_value()); // 設置值 item++; } } } } QuartzTaskService service = new QuartzTaskService(InterList.get(0).getName(), map, jdbcTemplate, qt); if (!"".equals(qt.getWarn_date_num()) && qt.getWarn_date_num() != null) { future = threadPoolTaskScheduler.schedule(service, new CronTrigger(qt.getWarn_date_num()));// 初始化任務,第二個參數是Cron表達式 if (future != null) { map_future.put("future", future); map_future.put("id", InterList.get(0).getItemId()); map_future.put("status", "0"); mapList.add(map_future); } } else { msg += " 監測項:" + qt.getProName() + " 監測頻次字段爲空,不能執行計劃!"; } } else { msg += " 監測項:" + qt.getProName() + " 沒有查找到接口配置信息"; } } else { msg += " 監測項:" + qt.getProName() + " 已經啓動,請不要重複啓動。"; } return msg; } }
3) 構建任務處理線程類
public class QuartzTaskService implements Runnable { private JdbcTemplate jdbcTemplate; private String proName; private List<String> maplist; private MonitorWarnItem item; public QuartzTaskService(String proName,List<String> maplist,JdbcTemplate jdbcTemplate ,MonitorWarnItem item){ this.proName=proName; this.maplist=maplist; this.jdbcTemplate=jdbcTemplate; this.item=item; } protected void executeInternal() throws JobExecutionException { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); StringBuffer bf=new StringBuffer(); bf.append("call "); bf.append(proName); bf.append("("); int i=1; for(String map:maplist){ if(i==maplist.size()){ // 最後一位 bf.append("'"+map+"')"); }else { bf.append("'" + map + "',"); } i++; } jdbcTemplate.batchUpdate(bf.toString()); System.out.println("執行了過程:" +proName+"當前參數順序:"+bf.toString()+ " 當前時間 "+ sdf.format(new Date())); } @Override public void run() { try { executeInternal(); // 調用執行 } catch (JobExecutionException e) { e.printStackTrace(); } }
4) 此處是用的List保存的任務信息,在項目重啓以後這個東西就沒了,也就是說定時任務就全丟了,so,這裏考慮使用數據庫來持久化保存調度任務信息, 或者在項目啓動的時候寫一個配置來調用啓動定時任務
@Component @Order(1) public class StartTask implements CommandLineRunner { @Autowired private TestService testService; public String setTask(){ Calendar cale = null; cale = Calendar.getInstance(); int year = cale.get(Calendar.YEAR); MonitorWarnItem itemList=testService.QueryByStatus ("1");// 根據狀態查詢須要啓動的監測項 if(itemList.size()>0){ // 存在須要啓動的檢測項 For(MonitorWarnItem qt: itemList) testService.initMonitor(qt);// 啓動任務列表和消息 } return ""; } @Override public void run(String... args) throws Exception { setTask (); } }
5)最後附上一個我使用的返回處理類
public class ResultInfo<T> { private Integer result; private String msg; private T rows; private int total; //省略其餘處理 }
5、 參考
Spring Scheduled定時任務動態修改cron參數
http://www.javashuo.com/article/p-qrbdgfyi-ex.html
接口 java.util.concurrent.ScheduledFuture的使用
https://www.runoob.com/manual/jdk1.6/java/util/concurrent/class-use/ScheduledFuture.html