在JavaEE系统中,我们经常会用到定时任务,比如每天晚上凌晨之后跑批处理或者是每天某个时刻群发消息等等.

我们可以使用java.util.Timer结合java.util.TimerTask来去完成需求,但是这种组合去调度会非常,代码量大且限制特别多.

所以出现了Quartz框架,Quartz与Spring可以非常好的集成,代码量少,且易于控制.下面我们来讲讲Spring与Quartz的集成,以及相关作业类及配置,还有corn表达式的用法.

需求:定时进行数据监测并发送邮件.

所用技术:spring+ strtus1 +hibernate

分析:首先接触到这个需求的时候,我想的是用TimeTask去完成,后来想了想TimeTask的缺陷: ①如果报错则无法进行之后的定时任务执行 ②对于时间上的设置不如Quartz好,所以决定用Quartz完成.  博主也是第一次用Quartz定时任务,有不足之处请之指出,互相学习.

首先,1.配置创建spring配置文件,在web-inf下我创建了applicationContext-task.xml并进行了配置. 配置bean的文件就不展示了,这里主要是将的怎么用Quartz完成定时发送邮件.

注:这里小讲一下配置文件中 <property  name="a"  ref="aa" />和<property   name="a"   ref bean ="b"/>的区别?

<property  name="a"  ref="aa" /> 就是找当前配置文件里的bean 也就是id为aa的bean

<property   name="a"   ref bean ="b"/>  就是找配置文件里的bean 也就是id为aa的bean.

2.进行包装作业配置

注:此处包装的是我们1中配置的bean,以及指定了1中class对应类的执行方法.

3.配置corn触发器  corn会在后面讲到.

注:红色框告诉我们,我们的corn配置是针对的哪一个bean,蓝色框是配置corn,此处是每两分钟执行一次定时任务.

4.建立实际调度,说白了就是最后一步的调用的配置

注:红色框是一个list集合,他可以配置很多调度,即:你可以写很多定时任务,这些定时任务可以用一个调度执行.

<ref  local=" ">这代表的是我们调度所寻找的是当前配置文件中的bean. 也可以这样配置 <ref bean=" "> 这是在所有配置中寻找bean.

到此,不要以为spring文件的配置结束了,我就是因为对spring的不熟悉以为spring配置完了,这里再次提醒新人在项目报错的时候一定要先关注日志.

在我们的web.xml中,我们配置了spring文件的初始化,我这里初始化的是webApplicationContext.xml这个文件,所以我还需要把我写的applicationContext-task.xml

下面是将我们写的spring配置导入初始化文件中并同时配置数据库连接,即web.xml初始化加载.

到此,spring文件结束.

下面是struts文件配置. 这里就快速的带过了,struts文件中只是写了一些映射,没有什么好写的.说一下struts配置文件的组成.

1.

注:这里配置的是映射中需要用到的是实体类.

2.

注:红色的为前端界面写的user下的所有.do都到这里起来寻找映射关系.蓝色的对应的action处理类.黑色的parameter="{1}"就是路径中的*,比如add.do *就是add.黄色的就是对应action处理类处理之后返回的字段对应的返回界面.

此处需要在web.xml中进行配置struts初始化以及拦截.

   

struts配置文件到此结束.

下面需要建立对应的定时任务类就可以.

 package com.ab.itws.common.job;

 import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.util.ArrayList;
import java.util.ResourceBundle; import org.apache.log4j.Logger; import com.ab.itws.common.Conts;
import com.ab.itws.common.DBUtil;
import com.ab.itws.common.Email;
import com.ab.itws.common.ExeSQL;
import com.ab.itws.common.PubFun;
import com.ab.itws.common.SSRS; import com.ab.itws.common.TenSQL;
import com.ab.itws.dbcheck.dto.TDBConfigDTO;
import com.ab.itws.dbcheck.dto.TPersonInfoDTO; import com.ab.itws.dbcheck.dto.TSqlCheckConfigDTO;
import com.ab.itws.dbcheck.dto.TSqlCheckResultDTO;
import com.ab.itws.dbcheck.service.IDBConfigManager;
import com.ab.itws.dbcheck.service.IPersonInfoManager;
import com.ab.itws.dbcheck.service.ISqlCheckConfigManager;
import com.ab.itws.dbcheck.service.ISqlCheckResultManager; /**
*
* @author liujw
* 2017-11-14
* 邮箱发送添加查询内容
*/ public class dataCheckQuartzNew {
// 数据源服务类
private IDBConfigManager myIDBConfigManager;
// 校验信息类
private ISqlCheckConfigManager myISqlCheckConfigManager;
// 用户信息类
private IPersonInfoManager myIPersonInfoManager; // 数据校验结果类
private ISqlCheckResultManager myISqlCheckResultManager; private java.util.List dbidlist;
private String dbids = "";
private String SMTPServer = "";
private String Subject = "新版数据校验结果";
private String From = "";
private String MailPWD = "";
private String Port = "";
private String To = "";
private String SendBody=""; //dataCheckQuartzNew日志
private static final Logger log = Logger.getLogger(dataCheckQuartzNew.class);
private static final SimpleDateFormat formatDate = new SimpleDateFormat("yyyyMMddHHmmss"); //定时操作 protected void executeNewjob(){ log.info("定时任务启动!! dataCheckQuartzNew -------start ------------"); if(!getCheckSQLCfg()){
log.error("读取邮箱信息发生异常,停止执行");
return;
}
Email tEmail = new Email(SMTPServer,From,MailPWD,To,Subject,Port);
TDBConfigDTO dbdto = new TDBConfigDTO();
try{
dbdto.setPageSize(999);
//根据下次执行时间查出可以选用的数据库
dbdto = this.myIDBConfigManager.listCanLinkTDBConfigDTO(dbdto);// 查询表为sqlconfig
dbidlist = dbdto.getResultList();
}catch(Exception e){
e.printStackTrace();
}
//记录任务执行时间,为计算下次执行时间时用,避免每天的执行时间都有变化
java.util.Calendar c = java.util.Calendar.getInstance();
//修改数据源下次执行时间用,C在下面需要减去DEFAULT_INTEVAL,在0点执行的时候会有问题,不能使用,需要重新创建一个cdb
java.util.Calendar cdb = java.util.Calendar.getInstance();
//批次号,根据日期时间
String strbatchno = formatDate.format(c.getTime());
log.info("strbatchno="+strbatchno);
c.add(java.util.Calendar.MINUTE, -Conts.DEFAULT_INTEVAL);
//从下面转移上了,解决由于dbidlist时提示信息没有被值空的问题
SendBody = "";
if(null != dbidlist){
log.info("开始定时数据源队列 数据校验!dbidlist size="+dbidlist.size());
log.info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
try {
//如果是多个数据源,需要单个执行
for(int i=0;i<dbidlist.size();i++){
//1.获取数据源信息
//2.获取该数据源所有的数据检查语句,执行语句
//3.获取该数据源的接受人,组装邮件内容发送email
TDBConfigDTO tdbConfigDto = (TDBConfigDTO)dbidlist.get(i); log.info("开始执行单个数据源数据校验!dbid="+i+"---"+tdbConfigDto.getDbCode());
Connection con = null;
try{
//获取数据库连接 通过查询出的可用的数据库查找对应的SQL
con = new DBUtil().getConnByDBTYPE(tdbConfigDto);
if(null != con){
//根据数据源信息,查询出所有该数据源下的数据检查记录,遍历执行
checkdataForDBSource(tdbConfigDto,con,c,strbatchno);
}else{
//获取数据库连接失败,直接跳出本次循环,执行下一个数据源
log.error(tdbConfigDto.getDbCode()+"获取数据库连接失败,跳过,执行下一个");
SendBody = SendBody+ tdbConfigDto.getDbCode()+"获取数据库连接失败。\n";
continue;
} }catch(Exception e){
log.error("执行数据源数据检查发生异常 dbid="+tdbConfigDto.getDbId()+",跳过,执行下一个");
SendBody = SendBody+"数据源数据检查发生异常dbid="+tdbConfigDto.getDbId()+"。\n";
e.printStackTrace();
}finally{
if(con != null){ // 关闭连接对象
try{
con.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
}
}
log.info("执行数据校验完成!");
//执行完数据检查操作以后,发送有问题的记录给用户(做判断,查出来的问题条数为0,则不发送邮件)
log.info("组装邮件内容给关系人开始!");
sentPersons(strbatchno);
log.info("组装邮件内容给关系人结束!"); log.info("置邮件发送状态开始!");
//改变邮件发送状态
setAllSendMailStatus(strbatchno);
log.info("置SQL为邮件发送状态结束!"); //因为短信功能尚未用到 所以注掉
/*//短信 此处的短信提醒是早期的功能,等后面的短信功能完善后可以删除此处代码
log.info("短信下发开始执行!");
Sms sms = new Sms();
sms.send(myISqlCheckConfigManager,strbatchno);
log.info("短信下发结束!");*/
} catch (Exception e) {
log.error("执行数据校验,错误信息:" + e.getMessage());
SendBody = SendBody+"执行数据校验,错误信息="+e.getMessage()+"。\n";
e.printStackTrace();
}
log.info("执行数据校验结束!");
}else{
log.error("dbidlist 为空,不执行批量操作!dbidlist="+dbidlist);
SendBody = SendBody+"配置参数 dbidlist 为空,不执行批量操作。\n";
} if(!SendBody.equals("")){
try{
tEmail.send(SendBody);
}catch(Exception e){
log.error("发送邮件发生异常,ERROR="+e.getMessage());
e.printStackTrace();
}
}
//}
} /**
* 检索数据源下的所有用户,根据数据检查的结果给每个接受人发送邮件
* @param tdbConfigDto
*/
public void sentPersons(String strbatchno){
//获取该数据源下的所有用户数据
try{
TPersonInfoDTO personInfodto = new TPersonInfoDTO();
//personInfodto.setDbId(tdbConfigDto.getDbId());
personInfodto.setPageSize(9999);
personInfodto = this.myIPersonInfoManager.serchPersonInfo(personInfodto);
java.util.List personInfodtolist = personInfodto.getResultList();
if(null != personInfodtolist&&personInfodtolist.size()>0){
//遍历用户,查询需要发送给它的记录
for(int i=0;i<personInfodtolist.size();i++){
TPersonInfoDTO temppersonInfodto = (TPersonInfoDTO)personInfodtolist.get(i);
String stremailcontent = this.getEmailContent(temppersonInfodto,strbatchno);
//如果邮件内容不为空,需要发送给用户
if(!"".equals(stremailcontent)){
try{
Email mEmail = new Email(SMTPServer,From,MailPWD,temppersonInfodto.getEmail(),"数据校验结果,请审阅",Port);
log.info("发送给用户"+temppersonInfodto.getName()+",邮件内容:"+stremailcontent);
mEmail.send(stremailcontent);
}catch (Exception ex) {
SendBody=SendBody+ "\t邮件发送失败,相关人员编码:" +temppersonInfodto.getPersonID()+"\n";
log.error("邮件发送失败!email="+temppersonInfodto.getEmail());
ex.printStackTrace();
}
} log.info("未发现异常数据,无需发送邮件");
}
}else{
log.error("该数据源下没有配置任何接受用户信息");
}
}catch(Exception e){
log.error("给数据源下的用户发送邮件发生异常 error="+e.getMessage());
e.printStackTrace();
}
}
/**
* 拼接所有需要发送给该用户的数据校验结果
* @param personInfodto
* @return
*/
public String getEmailContent(TPersonInfoDTO personInfodto,String strbatchno){
String stremailcontent = "";
String strSmsconttent = "";
try{
TSqlCheckConfigDTO tsqlcheckconfigdto = new TSqlCheckConfigDTO();
tsqlcheckconfigdto.setDbId(personInfodto.getDbId());
tsqlcheckconfigdto.setPersonID(personInfodto.getPersonID());
tsqlcheckconfigdto.setPageSize(9999);
tsqlcheckconfigdto.setValiFlag(Conts.STATUS_ABLE);
tsqlcheckconfigdto.setSendMail(Conts.MAIL_NOT_SEND); //未发邮件的记录
tsqlcheckconfigdto.setBatch(strbatchno);
tsqlcheckconfigdto = this.myISqlCheckConfigManager.serchSqlCheckConfig(tsqlcheckconfigdto);
java.util.List sqlcheckconfiglist = tsqlcheckconfigdto.getResultList();
//判断是否配置了 数据检查sql
if(null != sqlcheckconfiglist&& sqlcheckconfiglist.size()>0){
//执行 数据检查工作 获取执行的 sql
for(int i=0;i<sqlcheckconfiglist.size();i++){ TSqlCheckConfigDTO temptsqlcheckconfigdto = (TSqlCheckConfigDTO)sqlcheckconfiglist.get(i);
//查询有错误记录的记录
if(!temptsqlcheckconfigdto.getErrCount().equals("0条")){
//查询有错误记录的记录
if(temptsqlcheckconfigdto.getErrCount().endsWith("条")){
// 2017/11/15 liujw 增加邮件内容 检查SQL 检查字段
stremailcontent = stremailcontent+"模块名称:"+temptsqlcheckconfigdto.getModuName()+"\t 模块代码:"+temptsqlcheckconfigdto.getModuCode()+"\t 校验结果:"+temptsqlcheckconfigdto.getErrCount()+"错误数据 \t 错误描述:"+temptsqlcheckconfigdto.getRemark()+"\n"+"执行SQL: "+temptsqlcheckconfigdto.getCalSql()+"\t 错误条数: "+temptsqlcheckconfigdto.getJobId()+"\n 错误信息: "+temptsqlcheckconfigdto.getJobName();
}else{
//执行sql时,发生异常的
stremailcontent = stremailcontent+"模块名称:"+temptsqlcheckconfigdto.getModuName()+"\t 模块代码:"+temptsqlcheckconfigdto.getModuCode()+"\t 校验结果:执行SQL发生异常,请检查SQL的正确性! \t \t 错误描述:"+temptsqlcheckconfigdto.getRemark()+"\n"+"执行SQL: "+temptsqlcheckconfigdto.getCalSql();
} /* //因为目前用不到短信功能 所以注掉 log.info("模块代码:"+temptsqlcheckconfigdto.getModuCode()+"是否进行短信提示,开始");
log.info("短信提示设置"+temptsqlcheckconfigdto.getSmsalert());
log.info("用户手机号"+personInfodto.getMobile()); //判断是否需要做短信提示
if(Conts.HAS_SMS_ALERT.equals(temptsqlcheckconfigdto.getSmsalert())){
log.info("准备发送提示短信-"+temptsqlcheckconfigdto.getModuCode());
//检查是否还可以发送短信提示
boolean sendsmsflag = this.sendSmsAlertCheck(temptsqlcheckconfigdto,personInfodto);
if(sendsmsflag){
this.sendSmsAlert(temptsqlcheckconfigdto,personInfodto);
}
}else{
log.info("不发送提示短信-"+temptsqlcheckconfigdto.getModuCode());
}*/
} }
//调用发送短信方法 }else{
log.error("sqlcheckconfig表中没有该用户可用的SQL查询语句,请去配置!personInfodto="+personInfodto.getName());
}
}catch(Exception e){
log.error("getEmailContent to person error personid="+personInfodto.getName());
e.printStackTrace();
}
return stremailcontent;
} //发送短信功能 目前用不到 注掉
/*private void sendSmsAlert(TSqlCheckConfigDTO tsqlcheckconfigdto,TPersonInfoDTO personInfodto){
try{
//组装TSMSLogDTO dto
TSMSLogDTO dto = new TSMSLogDTO();
dto.setCalCode(tsqlcheckconfigdto.getCalCode());
dto.setPersonID(personInfodto.getPersonID());
dto.setMobile(personInfodto.getMobile());
dto.setAlertType(Conts.SMS_CK_ALERT);
String strcontent = "模块名称:"+tsqlcheckconfigdto.getModuName()+"\t模块代码:"+tsqlcheckconfigdto.getModuCode()+"\t 校验结果:"+tsqlcheckconfigdto.getErrCount()+"错误数据 \t 错误描述:"+tsqlcheckconfigdto.getRemark();
dto.setContent(strcontent);
//超过300个字,截取300,
if(strcontent.length()>300){
strcontent= strcontent.substring(0,300)+"....更多内容,请查看邮件..";
}
log.info("请求短信平台mobile="+personInfodto.getMobile()+",strcontent="+strcontent);
Sms sms = new Sms();
String sendresult = sms.send(personInfodto.getMobile(), strcontent);
log.info("请求短信平台,返回结果="+sendresult);
if(sendresult.length()>50)
sendresult=sendresult.substring(0,49);
dto.setStrresult(sendresult);
if(null!=sendresult&&sendresult.startsWith("result=0")){
dto.setStatus(Conts.SMS_SEND_OK);
}else{
dto.setStatus(Conts.SMS_SEND_ERROR);
}
this.myISMSLogManager.addSMSLog(dto);
}catch(Exception e){
log.error("发送短信提示信息错误"+e.getMessage());
e.printStackTrace();
}
}*/ //发送短信功能 目前用不到 注掉
/*private boolean sendSmsAlertCheck(TSqlCheckConfigDTO tsqlcheckconfigdto,TPersonInfoDTO personInfodto){
//1:判断手机号码,2:查询发送短信记录(根据modecode与手机号码),如果超过每小时、每天限量,不在发送
//3.调用发送短信方法,4.记录发送的log
Boolean cansend = false;
try{
log.info("判断是否短信 提示方法开始执行:modecode="+tsqlcheckconfigdto.getModuCode()+",mobile="+personInfodto.getMobile());
if(null==personInfodto.getMobile()||"".equals(personInfodto.getMobile())){
log.info("判断是否短信 ,手机号为空,不做发送");
return cansend;
}
Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
Matcher m = p.matcher(personInfodto.getMobile());
log.info("判断是否短信提示,手机号码"+personInfodto.getMobile()+",验证结果="+m.matches());
if(m.matches()){
int daymaxnum = 5,hourmaxnum=3;
try{
ResourceBundle rb = ResourceBundle.getBundle("smsconfig");
String strdaymax = rb.getString("dayMax");
if(null != strdaymax){
daymaxnum = Integer.parseInt(strdaymax);
}
String strhourmax = rb.getString("hourMax");
if(null != strhourmax){
hourmaxnum = Integer.parseInt(strhourmax);
}
log.info("系统配置,每天最大发送"+strdaymax+",每小时最大发送="+strhourmax);
}catch(Exception e){
log.info("读取配置文件设置失败,使用默认的配置"+e.getMessage());
} TSMSLogDTO dto = new TSMSLogDTO();
dto.setCalCode(tsqlcheckconfigdto.getModuCode());
dto.setMobile(personInfodto.getMobile());
java.util.List daysmslist = this.myISMSLogManager.serchSMSLogByDay(dto, null).getResultList();
java.util.List hoursmslist = this.myISMSLogManager.serchSMSLogByHour(dto, null).getResultList();
log.info("已发送数量查询,今天发送="+daysmslist.size()+",本小时发送="+hoursmslist.size());
if(daymaxnum>daysmslist.size()){
if(hourmaxnum>hoursmslist.size()){
cansend = true;
}else{
log.info("短信提示超过一小时最大限额,不发送短信提示,"+personInfodto.getMobile());
}
}else{
log.info("短信提示已超过一天的最大限额,不发送短信提示,"+personInfodto.getMobile());
} }else{
log.info("短信提示无法发送,原因手机号格式不对,"+personInfodto.getMobile());
} }catch(Exception e){
log.error("判断是否发送提示短信错误:"+e.getMessage());
e.printStackTrace();
}
return cansend;
}*/ /**
* 查出所有关系人,遍历属于它的检查语句
* 置所有的检查语句邮件发送状态为已发送
* @param tdbConfigDto
*/
public void setAllSendMailStatus(String strbatchno){
//获取该数据源下的所有用户数据
try{
TPersonInfoDTO personInfodto = new TPersonInfoDTO();
//personInfodto.setDbId(tdbConfigDto.getDbId());
personInfodto.setPageSize(9999);
personInfodto = this.myIPersonInfoManager.serchPersonInfo(personInfodto);
java.util.List personInfodtolist = personInfodto.getResultList();
if(null != personInfodtolist&&personInfodtolist.size()>0){
//遍历用户,查询出结果需要抄送给他的检查语句,置为已发送
for(int i=0;i<personInfodtolist.size();i++){
TPersonInfoDTO temppersonInfodto = (TPersonInfoDTO)personInfodtolist.get(i);
getAllSQLforPerson(temppersonInfodto,strbatchno);
}
}else{
log.error("该数据源下没有配置任何接受用户信息");
}
}catch(Exception e){
log.error("给数据源下的用户发送邮件发生异常 error="+e.getMessage());
e.printStackTrace();
}
} /**
* 拼接所有需要发送给该用户的数据校验结果
* @param personInfodto
* @return
*/
public void getAllSQLforPerson(TPersonInfoDTO personInfodto,String strbatchno){
String stremailcontent = "";
try{
TSqlCheckConfigDTO tsqlcheckconfigdto = new TSqlCheckConfigDTO();
tsqlcheckconfigdto.setPersonID(personInfodto.getPersonID());
tsqlcheckconfigdto.setPageSize(9999);
tsqlcheckconfigdto.setValiFlag(Conts.STATUS_ABLE);
tsqlcheckconfigdto.setSendMail(Conts.MAIL_NOT_SEND); //未发邮件的记录
tsqlcheckconfigdto.setBatch(strbatchno); //同一批次
tsqlcheckconfigdto = this.myISqlCheckConfigManager.serchSqlCheckConfig(tsqlcheckconfigdto);
java.util.List sqlcheckconfiglist = tsqlcheckconfigdto.getResultList();
//判断是否配置了 数据检查sql
if(null != sqlcheckconfiglist&& sqlcheckconfiglist.size()>0){
//执行 数据检查工作 获取执行的 sql
log.info("置执行状态为执行完成,邮件已发送开始");
for(int i=0;i<sqlcheckconfiglist.size();i++){
TSqlCheckConfigDTO temptsqlcheckconfigdto = (TSqlCheckConfigDTO)sqlcheckconfiglist.get(i);
temptsqlcheckconfigdto.setSendMail(Conts.MAIL_ALREADY_SEND);
temptsqlcheckconfigdto.setStatus(Conts.SQL_RUN_OK);
this.myISqlCheckConfigManager.updateSqlCheckConfig(temptsqlcheckconfigdto);
}
log.info("置执行状态为执行完成,邮件已发送结束");
}else{
log.error("getAllSQLforPerson表中没有该用户需要接受的记录!personInfodto="+personInfodto.getName());
}
}catch(Exception e){
log.error("getAllSQLforPerson to person error personid="+personInfodto.getPersonID()+";stremailcontent="+stremailcontent);
e.printStackTrace();
}
} private void checkdataForDBSource(TDBConfigDTO tdbConfigDto,Connection conn,java.util.Calendar c,String strbatchno){
//1.获取所有的执行sql,2.通过建立的连接,执行相应的sql,3.记录操作结果
//1.获取SqlCheckConfig 列表,根据数据源id
try{
//查询出该数据源下的所有执行完成,并且下次执行时间小于等于当前时间
TSqlCheckConfigDTO tsqlcheckconfigdto = new TSqlCheckConfigDTO();
tsqlcheckconfigdto.setDbId(tdbConfigDto.getDbId());
tsqlcheckconfigdto.setPageSize(9999);
tsqlcheckconfigdto.setStatus("0,2"); //不查询执行中的SQL
tsqlcheckconfigdto.setValiFlag(Conts.STATUS_ABLE); //可用
tsqlcheckconfigdto.setNextRunTime(new java.util.Date());
//通过给定的查询条件查询出所有可执行的SQL
tsqlcheckconfigdto = this.myISqlCheckConfigManager.getNeedRunTSqlCheckConfigDTO(tsqlcheckconfigdto);
java.util.List sqlcheckconfiglist = tsqlcheckconfigdto.getResultList();
//判断是否配置了 数据检查sql
if(null != sqlcheckconfiglist&& sqlcheckconfiglist.size()>0){ //2.通过建立的连接,执行相应的sql
log.info("置执行状态为执行中开始");
for(int i=0;i<sqlcheckconfiglist.size();i++){
//遍历所有检查配置记录,首先置执行状态为执行中,设置批次号
TSqlCheckConfigDTO temptsqlcheckconfigdto1 = (TSqlCheckConfigDTO)sqlcheckconfiglist.get(i);
temptsqlcheckconfigdto1.setStatus(Conts.SQL_RUNNING);
temptsqlcheckconfigdto1.setBatch(strbatchno);
this.myISqlCheckConfigManager.updateSqlCheckConfig(temptsqlcheckconfigdto1);
}
log.info("置执行状态为执行中结束");
log.info("遍历执行检查配置记录开始");
for(int j=0;j<sqlcheckconfiglist.size();j++){
//遍历所有检查配置记录
TSqlCheckConfigDTO temptsqlcheckconfigdto = (TSqlCheckConfigDTO)sqlcheckconfiglist.get(j);
checkdataByTSqlCheckConfigDTO(temptsqlcheckconfigdto,conn,c);
}
log.info("遍历执行检查配置记录结束");
}else{
log.error("StatSqlConfig表中没有需要执行的检查语句!");
} }catch(Exception e){ }
} /**
* 执行单个 检查sql的执行
* @param temptsqlcheckconfigdto
*/
private void checkdataByTSqlCheckConfigDTO(TSqlCheckConfigDTO temptsqlcheckconfigdto,Connection conn,java.util.Calendar c){
long starttime = System.currentTimeMillis();
try{ //首先置执行状态为执行中
temptsqlcheckconfigdto.setStatus(Conts.SQL_RUNNING);
this.myISqlCheckConfigManager.updateSqlCheckConfig(temptsqlcheckconfigdto); SSRS rSSRS = new SSRS();
//2017/11/21 新增接受查询数据库信息集合
ArrayList<TenSQL> list = new ArrayList<TenSQL>();
//2017/11/15 查询字段放置类
//TenSQL tensql = new TenSQL(); ExeSQL tExeSQL = new ExeSQL(conn);
String tCalSql = temptsqlcheckconfigdto.getCalSql();
tCalSql = tCalSql.replaceAll("’", "'").replaceAll("‘", "'");
if(tCalSql.startsWith("update")||tCalSql.startsWith("insert")||tCalSql.startsWith("delete")){
//暂时屏蔽,如果需要是还原
rSSRS = tExeSQL.execUPDATESQL(tCalSql);
//rSSRS = tExeSQL.execSQL("select count(*) from (" + tCalSql + ") gq");
}else{
// 2017/11/14 liujw 正式查询SQL
//rSSRS = tExeSQL.execSQL("select count(*) from (" + tCalSql + ") gq");
list = tExeSQL.execSQLNew(tCalSql);
} java.util.Date curtime = new java.util.Date();
int m = 0;
String listvalue = "";
//执行没有出错
if (tExeSQL.mErrors.getErrorCount() == 0) {
if (/*rSSRS*/ list!= null) {
// 输出集合list中的每条数据
for(int i = 0;i<list.size();i++){
log.info(list.get(i));
listvalue += list.get(i)+"\r 下一条:";
m = list.size();
}
/* m = rSSRS.getMaxCol();
*/
} else {
m = 0;
} /*// for(int i=1;i<=m;i++){
// SQLvalue += (rSSRS.GetText(0, i)+",");
// }
//
*/ //更新 检查数据sql记录 ErrCount ,ValiFlag makedate maketime
temptsqlcheckconfigdto.setErrCount(m+"条");
temptsqlcheckconfigdto.setValiFlag(Conts.STATUS_ABLE);
temptsqlcheckconfigdto.setMakeDate(curtime);
temptsqlcheckconfigdto.setMakeTime(PubFun.getCurrentTime());
// 2017/11/22 liujw 新增字段 检查结果的错误信息
temptsqlcheckconfigdto.setJobName(listvalue);
if(m>0){
//插入一条检查记录sqlcheckresult
TSqlCheckResultDTO tsqlcheckresultdto = new TSqlCheckResultDTO();
tsqlcheckresultdto.setCalCode(temptsqlcheckconfigdto.getCalCode());
tsqlcheckresultdto.setDbId(temptsqlcheckconfigdto.getDbId());
tsqlcheckresultdto.setCkTimes(Long.valueOf(System.currentTimeMillis() - starttime).intValue());
tsqlcheckresultdto.setErrCount(m+"条");
tsqlcheckresultdto.setMakeDate(curtime);
tsqlcheckresultdto.setMakeTime(PubFun.getCurrentTime());
// 2017/11/15 liujw 将查出的值赋值给JOB_ID字段
//2017/11/21 liujw
tsqlcheckresultdto.setJOB_ID(listvalue);
myISqlCheckResultManager.addSqlCheckResult(tsqlcheckresultdto);
}
}else {
temptsqlcheckconfigdto.setErrCount("SQL中的表或字段不存在");
//temptsqlcheckconfigdto.setValiFlag(Conts.STATUS_ABLE);
temptsqlcheckconfigdto.setMakeDate(curtime);
temptsqlcheckconfigdto.setMakeTime(PubFun.getCurrentTime());
} //置邮件发送状态为未发送
temptsqlcheckconfigdto.setSendMail(Conts.MAIL_NOT_SEND);
java.util.Calendar c2 = java.util.Calendar.getInstance();
//以执行开始的时间为基数计数下次执行时间,这样保证下次执行时间不会由于执行过程中花费的时间,而导致下次执行时间每次不一样
//c2.set(java.util.Calendar.HOUR_OF_DAY, c.get(java.util.Calendar.HOUR_OF_DAY));
//c2.set(java.util.Calendar.MINUTE, c.get(java.util.Calendar.MINUTE));
//c2.add(java.util.Calendar.MINUTE, temptsqlcheckconfigdto.getTimeInteval());
//为解决如果应用故障了,根据上次执行时间,修改下次执行时间。
java.util.Calendar cpre = java.util.Calendar.getInstance();
cpre.setTime(temptsqlcheckconfigdto.getNextRunTime());
cpre.add(java.util.Calendar.MINUTE, temptsqlcheckconfigdto.getTimeInteval()); log.info("执行"+temptsqlcheckconfigdto.getModuName()+":"+temptsqlcheckconfigdto.getModuCode()+":"+cpre.getTime());
temptsqlcheckconfigdto.setNextRunTime(cpre.getTime()); long usertime = System.currentTimeMillis() - starttime;
temptsqlcheckconfigdto.setUseTime(Long.valueOf(usertime).intValue());
this.myISqlCheckConfigManager.updateSqlCheckConfig(temptsqlcheckconfigdto); }catch(Exception e){
//置邮件发送状态为未发送
temptsqlcheckconfigdto.setSendMail(Conts.MAIL_NOT_SEND);
java.util.Calendar c2 = java.util.Calendar.getInstance();
//以执行开始的时间为基数计数下次执行时间,这样保证下次执行时间不会由于执行过程中花费的时间,而导致下次执行时间每次不一样
//c2.set(java.util.Calendar.HOUR_OF_DAY, c.get(java.util.Calendar.HOUR_OF_DAY));
//c2.set(java.util.Calendar.MINUTE, c.get(java.util.Calendar.MINUTE));
//c2.add(java.util.Calendar.MINUTE, temptsqlcheckconfigdto.getTimeInteval());
//为解决如果应用故障了,根据上次执行时间,修改下次执行时间。
java.util.Calendar cpre = java.util.Calendar.getInstance();
cpre.setTime(temptsqlcheckconfigdto.getNextRunTime());
cpre.add(java.util.Calendar.MINUTE, temptsqlcheckconfigdto.getTimeInteval());
log.error("执行"+temptsqlcheckconfigdto.getModuName()+":"+temptsqlcheckconfigdto.getModuCode()+":"+cpre.getTime());
temptsqlcheckconfigdto.setNextRunTime(cpre.getTime());
long usertime = System.currentTimeMillis() - starttime;
temptsqlcheckconfigdto.setUseTime(Long.valueOf(usertime).intValue());
try{
this.myISqlCheckConfigManager.updateSqlCheckConfig(temptsqlcheckconfigdto);
}catch(Exception e1){
} log.error("执行单个 检查sql的发生异常,error="+e.getMessage() +",sql="+temptsqlcheckconfigdto.getCalSql());
e.printStackTrace();
}
} //从配置文件获取邮箱信息
public boolean getCheckSQLCfg()
{
try {
//ResourceByndle java.util 读取信息 本地化国际化 会自动寻找mainconfig.properties文件
ResourceBundle rb = ResourceBundle.getBundle("mailconfig");
SMTPServer = rb.getString("SMTPServer");
From = rb.getString("From");
MailPWD = rb.getString("MailPWD");
To = rb.getString("To");
Port = rb.getString("Port");
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("读取邮箱信息配置文件mailconfig error="+e.getMessage());
e.printStackTrace();
return false;
}
return true;
} public IDBConfigManager getMyIDBConfigManager() {
return myIDBConfigManager;
} public void setMyIDBConfigManager(IDBConfigManager myIDBConfigManager) {
this.myIDBConfigManager = myIDBConfigManager;
} public ISqlCheckConfigManager getMyISqlCheckConfigManager() {
return myISqlCheckConfigManager;
} public void setMyISqlCheckConfigManager(
ISqlCheckConfigManager myISqlCheckConfigManager) {
this.myISqlCheckConfigManager = myISqlCheckConfigManager;
} public IPersonInfoManager getMyIPersonInfoManager() {
return myIPersonInfoManager;
} public void setMyIPersonInfoManager(IPersonInfoManager myIPersonInfoManager) {
this.myIPersonInfoManager = myIPersonInfoManager;
} public ISqlCheckResultManager getMyISqlCheckResultManager() {
return myISqlCheckResultManager;
} public void setMyISqlCheckResultManager(
ISqlCheckResultManager myISqlCheckResultManager) {
this.myISqlCheckResultManager = myISqlCheckResultManager;
} public java.util.List getDbidlist() {
return dbidlist;
}
public void setDbidlist(java.util.List dbidlist) {
this.dbidlist = dbidlist;
}
public String getDbids() {
return dbids;
}
public void setDbids(String dbids) {
this.dbids = dbids;
}
public String getSMTPServer() {
return SMTPServer;
}
public void setSMTPServer(String sMTPServer) {
SMTPServer = sMTPServer;
}
public String getSubject() {
return Subject;
}
public void setSubject(String subject) {
Subject = subject;
}
public String getMailPWD() {
return MailPWD;
}
public void setMailPWD(String mailPWD) {
MailPWD = mailPWD;
}
public String getFrom() {
return From;
}
public void setFrom(String from) {
From = from;
}
public String getPort() {
return Port;
}
public void setPort(String port) {
Port = port;
}
public String getSendBody() {
return SendBody;
}
public void setSendBody(String sendBody) {
SendBody = sendBody;
}
}
package com.ab.itws.common;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException; import org.apache.log4j.Logger; import com.ab.itws.dbcheck.dto.TDBConfigDTO; public class DBUtil { private static final Logger log = Logger.getLogger(DBUtil.class); public Connection getConnByDBTYPE(TDBConfigDTO tdbConfigDto){
Connection conn = null;
if(null != tdbConfigDto){
String IP = tdbConfigDto.getIp();
String Port = tdbConfigDto.getPort();
String DBName = tdbConfigDto.getDbSid();
String UserName = tdbConfigDto.getDbUser();
String PassWord = tdbConfigDto.getPassWord();
String dbType= tdbConfigDto.getDbType();
if(null==dbType||"".equals(dbType)){
dbType= Conts.DBTYPE_ORACLE;
}
if(dbType.equals(Conts.DBTYPE_ORACLE)){
log.info("开始获取oracle数据库连接");
conn = this.getOracleConn(tdbConfigDto);
}else if(dbType.equals(Conts.DBTYPE_DB2)){
log.info("开始获取db2数据库连接");
conn = this.getDB2Conn(tdbConfigDto);
}else if(dbType.equals(Conts.DBTYPE_MYSQL)){
log.info("开始获取mysql数据库连接");
conn = this.getMySQLConn(tdbConfigDto);
}else if(dbType.equals(Conts.DBTYPE_SQLSERVER)){
log.info("开始获取sqlserver数据库连接");
conn = this.getSQLServerConn(tdbConfigDto);
}else{
log.info("数据类型无对应的获取连接方法,dbType="+dbType);
}
}
return conn;
} /**
* 获取oracle数据库连接
* @param tdbConfigDto
* @return
*/
public Connection getOracleConn(TDBConfigDTO tdbConfigDto){
Connection conn = null;
if(null != tdbConfigDto){
String IP = tdbConfigDto.getIp();
String Port = tdbConfigDto.getPort();
String DBName = tdbConfigDto.getDbSid();
String UserName = tdbConfigDto.getDbUser();
String PassWord = tdbConfigDto.getPassWord();
String dbUrl = "jdbc:oracle:thin:"+UserName+"/"+PassWord+"@"+IP+":"+Port+":"+DBName;
try {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn=DriverManager.getConnection(dbUrl,UserName,PassWord);
} catch (Exception e) {
log.error("数据库连接失败");
//给数据源创建者发送邮件
e.printStackTrace();
}
}
return conn;
} /**
* 获取DB2数据库连接
* @param tdbConfigDto
* @return
*/
public Connection getDB2Conn(TDBConfigDTO tdbConfigDto){
Connection conn = null;
if(null != tdbConfigDto){
String IP = tdbConfigDto.getIp();
String Port = tdbConfigDto.getPort();
String DBName = tdbConfigDto.getDbSid();
String UserName = tdbConfigDto.getDbUser();
String PassWord = tdbConfigDto.getPassWord();
String dbUrl = "jdbc:db2://"+IP+":"+Port+"/"+DBName;
try {
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();
conn=DriverManager.getConnection(dbUrl,UserName,PassWord);
} catch (Exception e) {
log.error("数据库连接失败");
//给数据源创建者发送邮件
e.printStackTrace();
}
}
return conn;
}
/**
* 获取MySQL数据库连接
* @param tdbConfigDto
* @return
*/
public Connection getMySQLConn(TDBConfigDTO tdbConfigDto){
Connection conn = null;
if(null != tdbConfigDto){
String IP = tdbConfigDto.getIp();
String Port = tdbConfigDto.getPort();
String DBName = tdbConfigDto.getDbSid();
String UserName = tdbConfigDto.getDbUser();
String PassWord = tdbConfigDto.getPassWord();
String dbUrl = "jdbc:mysql://"+IP+":"+Port+"/"+DBName+ "?useUnicode=true&characterEncoding=GB2312";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn=DriverManager.getConnection(dbUrl,UserName,PassWord);
} catch (Exception e) {
log.error("数据库连接失败");
//给数据源创建者发送邮件
e.printStackTrace();
}
}
return conn;
}
/**
* 获取SQLServer数据库连接
* @param tdbConfigDto
* @return
*/
public Connection getSQLServerConn(TDBConfigDTO tdbConfigDto){
Connection conn = null;
if(null != tdbConfigDto){
String IP = tdbConfigDto.getIp();
String Port = tdbConfigDto.getPort();
String DBName = tdbConfigDto.getDbSid();
String UserName = tdbConfigDto.getDbUser();
String PassWord = tdbConfigDto.getPassWord();
String dbUrl = "jdbc:sqlserver://"+IP+":"+Port+";DatabaseName="+DBName;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
conn=DriverManager.getConnection(dbUrl,UserName,PassWord);
} catch (Exception e) {
log.error("数据库连接失败");
//给数据源创建者发送邮件
e.printStackTrace();
}
}
return conn;
} /**
* @author liujw 2017/11/21
* @param rs 查询的结果集
* @param c 结果集的一条记录,一条记录对应一个dao
* @return
* @throws SQLException
*/ public static Object getFirstObjectFromRs(ResultSet rs,Class<?> c)throws SQLException{
Object o = null;
try{
o= initObjectFromRsIfExist(rs, c);
}catch (Exception e) {
log.error("实例化"+c+"出错,我也不知道为嘛自己看");
e.printStackTrace();
} return o;
} /**
* @author liujw 2017/11/21
* 把数据库的一条记录映射到相应的dao对象中,
* 如果dao中的字段与数据库字段不一致,返回的就是dao数据类型定义的默认值
* 如:dao的字段String contno;而数据库的字段是contno_id,那么返回的就对应的默认值"".
* @param rs 查询的结果集
* @param c 结果集的一条记录,一条记录对应一个dao
* @return
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SQLException
*
*/
private static Object initObjectFromRsIfExist(ResultSet rs, Class<?> c) throws InstantiationException, IllegalAccessException, SQLException { Object o = c.newInstance(); //实例化新对象dao
Method[] methods = o.getClass().getMethods(); //得到dao的所有方法
String ff;
for(Method m : methods){
ff = m.getName().substring(3);//得到dao字段 get/set方法 从第三个字节截取
//查询dao映射的字段是否在记录在数据库包含的字段,dao方法对set开头的方法进行处理
//因为要将结果集映射到dao里面
if(m.getName().startsWith("set") && rsContainsFields(rs, ff)){
try{
m.invoke(o, getParamValueFromRs(rs, m));
}catch(IllegalArgumentException e) {
log.error(e);
throw new RuntimeException("IllegalArgumentException:" + e + "\nMethods:" + m.getName());
}catch (Exception e) {
log.error(e);
throw new RuntimeException("InvocationTargetException:" + e + "\nMethods:" + m.getName());
}
}
}
return o;
} /**
* 2017/11/21 liujw
* @param rs 查询的结果集
* @param m dao映射字段对应的一个set方法
* @return
* @throws SQLException
*/
private static Object getParamValueFromRs(ResultSet rs, Method m) throws SQLException { String ff = m.getName().substring(3); //得到dao的字段名
Type type = m.getGenericParameterTypes()[0];//获取set方法参数的类型
return getValueFromRs(rs, ff, type); } /**
* 获取数据库一条记录的一个列值
* @param rs 查询的结果集
* @param ff dao数据字段,也就是数据库记录的数据字段类型
* @param t 参数的数据类型
* @return
* @throws SQLException
*/
private static Object getValueFromRs(ResultSet rs, String ff, Type t) throws SQLException {
String type = t.toString();
try{
//因为目前定影的字段类型都是String 且String比较好用 建议都用String
if(type.equals("int") || type.equals("class java.lang.Integer")){
return rs.getInt(ff);
}else if(type.equals("class java.lang.String")){
return rs.getString(ff); }
}catch(SQLException e){
throw new SQLException("SQLException when get field:" + ff + "\n" + e);
}
throw new RuntimeException("getValueFromRsByField fail, field type is:" + type + ",field name is:" + ff);
} /**
* 查询dao映射的字段是否在记录在数据库包含的字段
* @param rs 查询的结果集
* @param ff dao映射的字段
* @return 如果包含在数据库记录集里面,返回true,否则false
* @throws SQLException
*/
private static boolean rsContainsFields(ResultSet rs, String ff) throws SQLException { ResultSetMetaData md = rs.getMetaData(); // 得到结果集(rs)的结构,比如字段数、字段名等。
for(int i = 0; i < md.getColumnCount(); i++){ //列数
if(md.getColumnName(i + 1).equalsIgnoreCase(ff)){
return true;
}
}
return false; } }

其他的一些零碎的配置和代码就不一一展示了,这里只把主要的配置和逻辑展示出来,如果有问题和想法请联系我.   代码比较繁琐,没有用注解,最近在学习注解.

Spring集成Quartz完成定时任务的更多相关文章

  1. ssh中使用spring的集成quartz 编写定时任务

    之前没有使用框架开发时对于开发定时任务都是 使用java的原声timer类,重写线程的run方法跑要执行的任务.刚刚换的新公司,项目使用ssh2,目前该项目中的定时任务的使用spirng集成的quar ...

  2. Spring Boot集成quartz实现定时任务并支持切换任务数据源

    org.quartz实现定时任务并自定义切换任务数据源 在工作中经常会需要使用到定时任务处理各种周期性的任务,org.quartz是处理此类定时任务的一个优秀框架.随着项目一点点推进,此时我们并不满足 ...

  3. 关于Spring集成Quartz的concurrent属性

    关于Spring集成Quartz的concurrent属性 以前经常在任务调度程序中使用Spring集成的Quartz,这种方式可以用简单的声明式配置即可实现定时任务,并结合了Spring自身的Bea ...

  4. Spring集成Quartz定时器

    <!-- Spring集成Quartz开始 --> <bean id="startQuertz" lazy-init="false" auto ...

  5. spring集成quartz

    spring集成quartz 注意:出现异常"Caused by: java.lang.IncompatibleClassChangeError: class org.springframe ...

  6. (十七)Spring 集成Quartz

    在使用jdk的timer时发现无法满足这次的开发需求:即无法在指定的日期进行执行任务.这便引入一个优秀的开源任务调度框架“quartz”.这里加入的是quartz-1.8.6版本.Quart的官网:h ...

  7. Quartz学习总结(1)——Spring集成Quartz框架

    一.Quartz简介 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简 ...

  8. SpringBoot集成Quartz实现定时任务

    1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考 ...

  9. Spring 集成Quartz

    在使用jdk的timer时发现无法在指定的日期进行执行任务.这便引入一个优秀的开源任务调度框架“quartz”.这里使用的是quartz-1.8.6版本.Quart的官网:http://www.qua ...

随机推荐

  1. Javascript 面向对象编程—封装

      前  言 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类) ...

  2. Java命令模式以及来自lambda的优化

    前言    设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...

  3. IDEA Maven 三层架构 2、运行 springMVC

    运行 SpringMVC 首先要理解 SpringMVC 应用程序的入口是配置文件 web.xml,其路径为"src/main/webapp/WEB-INF/web.xml",通过 ...

  4. caffe源码 池化层 反向传播

    图示池化层(前向传播) 池化层其实和卷积层有点相似,有个类似卷积核的窗口按照固定的步长在移动,每个窗口做一定的操作,按照这个操作的类型可以分为两种池化层: 输入参数如下: 输入: 1 * 3 * 4 ...

  5. 知识树杂谈Android面试(3)

    一.Activity生命周期? a. Activity四种状态? Running.Paused(透明无焦点).Stopped.killed. b. OnStart() OnRusume区分? 是否可以 ...

  6. 构造函数,This关键字

    构造函数: 即构建创造对象时调用的函数.在new的时候自动执行,给对象进行初始化.创建对象都必须要通过构造函数初始化.(有参和无参) 一个类中如果没有定义过构造函数,那么类中会有一个默认的空参数构造函 ...

  7. #tensorflow入门(1)

    tensorflow入门(1) 关于 TensorFlow TensorFlow™ 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库.节点(Nodes)在图中表示数学操 ...

  8. Django数据库操作性能相关

    Django数据库操作性能相关 案例: 现在我们的数据库中有两张表如下: 1.职员表: class UserInfo(models.Model): name = models.CharField(ma ...

  9. LeetCode 530. Minimum Absolute Difference in BST (二叉搜索树中最小绝对差)

    Given a binary search tree with non-negative values, find the minimum absolute difference between va ...

  10. LeetCode 229. Majority Element II (众数之二)

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...