Spring集成Quartz完成定时任务
在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完成定时任务的更多相关文章
- ssh中使用spring的集成quartz 编写定时任务
之前没有使用框架开发时对于开发定时任务都是 使用java的原声timer类,重写线程的run方法跑要执行的任务.刚刚换的新公司,项目使用ssh2,目前该项目中的定时任务的使用spirng集成的quar ...
- Spring Boot集成quartz实现定时任务并支持切换任务数据源
org.quartz实现定时任务并自定义切换任务数据源 在工作中经常会需要使用到定时任务处理各种周期性的任务,org.quartz是处理此类定时任务的一个优秀框架.随着项目一点点推进,此时我们并不满足 ...
- 关于Spring集成Quartz的concurrent属性
关于Spring集成Quartz的concurrent属性 以前经常在任务调度程序中使用Spring集成的Quartz,这种方式可以用简单的声明式配置即可实现定时任务,并结合了Spring自身的Bea ...
- Spring集成Quartz定时器
<!-- Spring集成Quartz开始 --> <bean id="startQuertz" lazy-init="false" auto ...
- spring集成quartz
spring集成quartz 注意:出现异常"Caused by: java.lang.IncompatibleClassChangeError: class org.springframe ...
- (十七)Spring 集成Quartz
在使用jdk的timer时发现无法满足这次的开发需求:即无法在指定的日期进行执行任务.这便引入一个优秀的开源任务调度框架“quartz”.这里加入的是quartz-1.8.6版本.Quart的官网:h ...
- Quartz学习总结(1)——Spring集成Quartz框架
一.Quartz简介 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简 ...
- SpringBoot集成Quartz实现定时任务
1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考 ...
- Spring 集成Quartz
在使用jdk的timer时发现无法在指定的日期进行执行任务.这便引入一个优秀的开源任务调度框架“quartz”.这里使用的是quartz-1.8.6版本.Quart的官网:http://www.qua ...
随机推荐
- SQLite中的时间日期函数
SQLite包含了如下时间/日期函数: datetime().......................产生日期和时间 date()...........................产生日期 t ...
- LinearGradientBrush,RadialGradientBrush的样式说明
LinearGradientBrush 使用线性渐变绘制区域.线性渐变沿直线定义渐变.该直线的终点由线性渐变的 StartPoint 和 EndPoint 属性定义.LinearGradientBru ...
- 学习总结---BGP协议
一.可以在自治域内使用BGP作为域内协议吗? 为什么?它和OSPF的关键差异是什么? 1.BGP的全称是边界网关协议,用于自治域间的路由传递,它不像OSPF协议,其重点不在于路由的计算,而在于路由的控 ...
- 在Visual Studio 2013 中使用C++单元测试
本文主要介绍在Visual Studio 2013中对代码进行单元测试的方法,包含了两方面的内容:对已有的Dll文件进行单元测试,以及对已有的源文件进行单元测试. 1. VS2013对DLL文件的单元 ...
- 敏捷开发(2)-Scrum
什么是SCRUM Scrum的英文意思是橄榄球运动的一个专业术语,表示“争球”的动作:把一个开发流程的名字取名为Scrum,我想你一定能想象出你的开发团队在开发一个项目时,大家像打橄榄球一样迅速.富有 ...
- Python学习笔记(九)
Python学习笔记(九): 装饰器(函数) 内置函数 1. 装饰器 1. 作用域 2. 高阶函数 3. 闭包 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就 ...
- 【NOIP2016提高组】 Day2 T1 组合数问题
题目传送门:https://www.luogu.org/problemnew/show/P2822 ↓题目大意↓ 数据的极限范围:n,m≤2000,k≤21,数据组数≤ ...
- Mysql Show ProcessList命令
每个MySql连接,或者叫线程,在任意一个给定的时间都有一个状态来标识正在进行的事情.可以使用 SHOW [FULL] PROCESSLIST 命令来查看哪些线程正在运行,及其查询状态,Command ...
- Yii2之AR类的坑与总结
本文主要记录本人从学习yii2到使用yii2开发项目过程中遇到的一些问题以及解决方法和知识点总结. 1. AR类关联哪个数据表? 默认情况下,AR类会根据类名称关联和类名相关的数据表,如:类名为Cou ...
- 事件轮询中的task与microtask
event loop 网上看到的一篇文章,关于介绍task和Tasks, microtasks, queues and schedules,尝试简单翻译一下写进来吧! 原文地址:https://jak ...