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