最近弄一功能,需要到点了自动办结日程。实现这个功能有两个办法,一个是使用线程,一个是使用数据库中的作业(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实例了。