使用執行緒實現“到點自動辦理”

wjiaoling136發表於2015-06-05

最近弄一功能,需要到點了自動辦結日程。實現這個功能有兩個辦法,一個是使用執行緒,一個是使用資料庫中的作業(SQL Server裡面有作業,其他的資料庫有木有不太清楚)。

 

基本思路是:在系統檔案裡配置倆變數:是否啟動自動辦結,自動辦結時間。系統啟動讀取“是否自動辦結”變數,若啟動就開啟一個執行緒。該執行緒不斷獲取當前時間,若當前時間與自動辦結時間相同或在5分鐘之內,就自動辦結待辦日程。

 

具體程式碼如下:

1、在配置檔案中配置變數:

startAutoEnd:1 是否啟動執行緒,設定為啟動

autoEndTime:12:30 自動辦結時間,這裡設定為12點半(設定成12點也行)

 

2、系統啟動時,新增程式碼是否啟動執行緒:

Integer startAutoEnd=0;
if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
	startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
}
if(startAutoEnd==1){//說明開啟自動辦結
	Thread th = new Thread(new com.wjl.AutoEndThread(),"autoEnd");
	th.start();//啟動執行緒
}
 

 3、AutoEndThread執行緒處理:

public class AutoEndThread implements Runnable {
	org.apache.log4j.Logger logger=Logger.getLogger(AutoEndThread.class);
	public void run() {
		autoEnd();
	}
	
	//日程記錄自動辦結
	private void autoEnd(){
		Integer startAutoEnd=0;
		String autoEndTime="";
		int hour=0,len=0,minite=0,sign=0,hour2=0,minite2=0;
		Calendar date = null;
		ExecSQL execSQL =null;
		StringBuffer sql =new StringBuffer();
		try {
			Thread.sleep(30000);//休眠半分鐘,等待其他資料初始化完成
			execSQL = (ExecSQL) SpringApplicationContextHolder.getSpringBean("ExecSQL");//獲取ExecSQL的bean
			while(true){
				//避免配置檔案在專案啟動過程中修改
				if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
					startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
				}
				if(startAutoEnd==1){//說明開啟自動辦結
					//獲取系統設定的自動辦結時間
					if(WebAppConfig.app("autoEndTime")!=null && !WebAppConfig.app("autoEndTime").equals("")){
						autoEndTime = WebAppConfig.app("autoEndTime");
					}
					
					if(autoEndTime!=null && !autoEndTime.equals("")){//說明有設定時間
						//變數初始化
						hour=0;
						len=0;
						minite=0;
						sign=0;
						sql.delete(0, sql.length());//清空StringBuffer
						
						//獲取設定的時間
						len=autoEndTime.split(":").length;
						if(len<2){//說明沒有冒號,那麼只有時沒有分
							autoEndTime = autoEndTime.replaceAll(":", "").replaceAll(":","");//替換冒號
							hour=Integer.parseInt(autoEndTime);
							minite=0;
						}else{
							hour = Integer.parseInt(autoEndTime.split(":")[0]);
							minite = Integer.parseInt(autoEndTime.split(":")[1]);
						}
						
						//獲取當前時間
						date = Calendar.getInstance();
						hour2=date.get(Calendar.HOUR_OF_DAY);
						minite2= date.get(Calendar.MINUTE);
//						System.out.println(autoEndTime+"\n"+hour+"\n"+hour2+"\n"+minite+"\n"+minite2);
						if((hour==hour2 && minite==minite2) || ((hour==hour2 && (minite2>minite) && (minite2-minite)<=5))){//說明當前時間即為設定的處理時間(或者5分鐘之內)
							sql.append("update S_TODOTASK set S_FINISH=1,S_FinishUserID=s.S_USER_ID,S_FinishDate=GETDATE(),S_FinishMemo='系統自動辦結' ");
							sql.append("from  S_SCHEDULE s where s.S_ID = S_TODOTASK.S_TableKey ");
							sql.append("and S_TODOTASK.S_ModuleID=0 and S_TODOTASK.S_VALID=1 ");
							sql.append("and S_TODOTASK.S_FINISH=0 and S_TODOTASK.S_AUTOEND=1 "); 
							sql.append("and datediff(day,S_TODOTASK.S_PlannedDate,GETDATE())=0");
							
//							System.out.println("自動辦結執行的SQL:"+sql.toString());
//							System.out.println("*******************************************************************************\n"+execSQL);
							sign = execSQL.execSQL(sql.toString());
							logger.debug("自動辦結執行的SQL:"+sql.toString()+"\n執行結果:"+sign);
							Thread.sleep(30000);//休眠半分鐘
						}
						
					}
				}
			}
			}catch (Exception e) {
				e.printStackTrace();
			}
	}
}
4、SpringApplicationContextHolder的getSpringBean()獲取ExecSQL例項(ExecSQL例項需要在Spring的配置檔案中進行配置):
public class SpringApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringApplicationContextHolder.context = context;
    }
    public static Object getSpringBean(String beanName) {
        return context==null?null:context.getBean(beanName);
    }
    public static String[] getBeanDefinitionNames() {
        return context.getBeanDefinitionNames();
    }
}
 

 5、ExecSQL中的execSQL方法用來執行SQL語句:

/***
 * 執行sql語句,insert、update、delete
 * 
 * @param sql
 * @return 1-成功,0-失敗
 */
public int execSQL(final String sql) throws Exception{
	log.debug("執行sql語句: " + sql);
	try {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
			return session.createSQLQuery(sql).executeUpdate();
		}
	});
	} catch (Exception re) {
		log.info("執行sql:[" + sql + "]失敗:" + re.getMessage());
		log.error("執行sql:[" + sql + "]失敗:" + re.getMessage(), re);
		throw re;
	}
}

 

6、說明:

專案中的ExcelSQL例項是直接從Spring的例項中獲取的,而不是直接New物件或者通過Spring重新註冊獲取,原因在於:

a、直接New:ExcelSQL物件不會為空,但是getHibernateTemplate()物件為空。

b、使用Spring註冊ExcelSQL,ExcelSQL物件為空。

最後就剩下直接從Spring中取ExcelSQL例項了。

相關文章