做了一个前台使用FLEX、后台使用JAVA、数据库使用的是ORACLE的这样一个工程.flex与java采用blazeDS进行通信。
项目中有个模块需要查询报警信息,而报警信息表的数据量又特别大,所以就根据报警信息表,在oracle中建立了几个分区。(每个月的数据是一个分区),进行分区查询。
--查询某个表下面某个分区的所有信息
select * from tmgpshis.tm_bus_warn_message_his PARTITION(P_WARN_MESSAGE_HIS_201304);
--表名必须要大写 查询某个表下面 所有的分区信息
SELECT PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME='TM_BUS_WARN_MESSAGE_HIS'
具体设计如下:
1 由于数据量非常大,在用户输入时间段查询数据的时候,限制了只能输入30天之内的数据。当然可以跨月查询。核心flex as代码如下:
//结束时间只能选择比开始时间小1个月的。
private function oneMonthControl(stTempStr:String,etTempStr:String):Boolean{
// 标志位
var isTimeFlag:Boolean = false ;
stTempStr = stTempStr.substring(0,4)+stTempStr.substring(5,7)+stTempStr.substring(8,10);
etTempStr = etTempStr.substring(0,4)+etTempStr.substring(5,7)+etTempStr.substring(8,10);
var sdataTime:Date = new Date(stTempStr.substring(0,4),stTempStr.substring(4,6),stTempStr.substr(6,8));
var gdataTime:Date = new Date(etTempStr.substring(0,4),etTempStr.substring(4,6),etTempStr.substr(6,8));
var num:Number = gdataTime.getTime() - sdataTime.getTime();
var millisecondsPerMinute:int = 1000 * 60;
var millisecondsPerHour:int = 1000 * 60 * 60;
var millisecondsPerDay:int = 1000 * 60 * 60 * 24;
var nday:Number = num / millisecondsPerDay;//日间隔
if(nday>30){
isTimeFlag=false;
}else{
isTimeFlag = true;
}
return isTimeFlag;
}
2 如果开始时间和结束时间,在当前时间的这一周内。直接查询这个当前表。核心flex as 代码如下:
//判断两个时间差 ,是否在当前时间一周内! private function decideTime(stTempStr:String,etTempStr:String):Boolean{ //得到系统的当前时间 var today:Date=new Date(); var dateFormatter:DateFormatter = new DateFormatter(); dateFormatter.formatString = "YYYYMMDD"; //YYYY-MM-DD JJ:NN:SS var now:String= dateFormatter.format(today); // 标志位 var isTimeFlag:Boolean = false ; stTempStr = stTempStr.substring(0,4)+stTempStr.substring(5,7)+stTempStr.substring(8,10); etTempStr = etTempStr.substring(0,4)+etTempStr.substring(5,7)+etTempStr.substring(8,10); var sdataTime:Date = new Date(stTempStr.substring(0,4),stTempStr.substring(4,6),stTempStr.substr(6,8)); var gdataTime:Date = new Date(etTempStr.substring(0,4),etTempStr.substring(4,6),etTempStr.substr(6,8)); var num:Number = gdataTime.getTime() - sdataTime.getTime(); var millisecondsPerMinute:int = 1000 * 60; var millisecondsPerHour:int = 1000 * 60 * 60; var millisecondsPerDay:int = 1000 * 60 * 60 * 24; var nday:Number = num / millisecondsPerDay;//日间隔 if(stTempStr.substring(4,6) == now.substring(4,6)){ //判定 if(nday >= 1 && nday<=6){ isTimeFlag=true; } } return isTimeFlag; }
//如果 开始时间和结束时间,在当前时间的这一周内。 if(decideTime(detailSt,detailEt)==true){ var token:AsyncToken = busAlermDetail.queryAlermDetailInfos(getSql(detailSt,detailEt)); FlexUtil.addResponder(token,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); //如果不是当前时间的当前一周。 }
3 如果不是当前时间的当前一周。先判断一下数据库中这个表是否有相应的分区。如果有相应的分区,则进行逻辑判断。核java代码,flex as 代码如下:
//查询到有分区 private function isHaveResHandler(event:ResultEvent):void{ isHavePar = event.result as String; //如果开始月份在分区里面,结束月份不在分区里面。 if(isHavePar=="1"){ var staOthSql:String=getStartPartSql(detailSt,detailEt)+"union"+" "+getotherPartSql(detailSt,detailEt); var staOthToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(staOthSql); FlexUtil.addResponder(staOthToken,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); } // 开始月份、结束月份都不在分区内 if(isHavePar=="2"){ var stetToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(getotherPartSql(detailSt,detailEt)); FlexUtil.addResponder(stetToken,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); } //如果开始月份不在分区里面,结束月份在分区里面。 if(isHavePar=="3"){ var othEndSql:String=getotherPartSql(detailSt,detailEt)+"union"+" "+getEndPartSql(detailSt,detailEt); var othEndToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(othEndSql); FlexUtil.addResponder(othEndToken,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); } //如果开始月份在分区里面,结束月份也在分区里面。 if(isHavePar=="4"){ //在同一分区中的月份 if(detailSt.substring(5,7)==detailEt.substring(5,7)){ //在同分区,不包括当前一周。 var sanToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(getEndPartSql(detailSt,detailEt)); FlexUtil.addResponder(sanToken,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); //开始月份与结束月份不一致 }else{ //开始分区并上结束分区 var unionsql:String=getStartPartSql(detailSt,detailEt)+"union"+" "+getEndPartSql(detailSt,detailEt); var unionToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(unionsql); FlexUtil.addResponder(unionToken,aAllConResultHandler,aAllConFaultHandler); UIWaiting.popWaiting(""); } } }
//得到分区sql private function getotherPartSql(stOther:String,etOther:String):String { partParam = "OTHER" ; var othersql:String="select t.bus_job_no busJobNo,to_char(t.ins_time,'YYYY-MM-DD HH24:MI:SS') insTime ,t.LINE_NO lineNo,t.warning_message warningMessage,t.warn_level warnLevel from tmgpshis.tm_bus_warn_message_his PARTITION (WARN_MESSAGE_"+partParam+") t where 1=1 "; if(line.selectedItem !=null && line.selectedItem!="") { othersql+=" and t.line_no ='"+line.selectedItem.id+"' "; } if(bus.selectedItem !=null && bus.selectedItem!="") { othersql+=" and t.bus_job_no ='"+bus.selectedItem.name+"' "; } if(conalermType.selectedItem != null && conalermType.selectedItem != ""){ trace(conalermType.selectedItem.ALERMTYPE as String); var alt:String =conalermType.selectedItem.ALERMTYPE as String ; othersql += " and t.WARNING_MESSAGE ='"+alt+"'"; } var otherasel:String=""; if(alermStateL.selectedItem == "未处理"){ otherasel="0"; }else if(alermStateL.selectedItem == "已处理"){ otherasel="1"; }else if(alermStateL.selectedItem == "将来处理"){ otherasel="2"; }else{ otherasel=""; } if(otherasel!="") { othersql+=" and t.ishandle="+otherasel+""; } othersql+=" and t.ins_time between TO_DATE('"+stOther+"', 'YYYY-MM-DD HH24:MI:SS')" + " and TO_DATE('"+etOther+"', 'YYYY-MM-DD HH24:MI:SS')"; othersql+=" and t.line_no in ("+lineNos+")"; return othersql; }
public String isHasPart(String stTime ,String etTime) { String resStr = "0" ; List<PartitionInfo> partBeanList = new ArrayList<PartitionInfo>(); partBeanList = queryAlermDetailInfoDao.isHasPart(); List<String> partNameStrList = new ArrayList<String>(); PartitionInfo po = new PartitionInfo(); for(int i=0;i<partBeanList.size();i++){ po = partBeanList.get(i); String parName = po.getPartitionName(); String monthN = rightStr(parName,2); partNameStrList.add(monthN); } if(partNameStrList.contains(stTime) && !partNameStrList.contains(etTime)){ resStr = "1" ; }else if(!partNameStrList.contains(stTime) && !partNameStrList.contains(etTime)){ resStr = "2" ; }else if(!partNameStrList.contains(stTime) && partNameStrList.contains(etTime)){ resStr = "3" ; }else if(partNameStrList.contains(stTime) && partNameStrList.contains(etTime)){ resStr = "4" ; } return resStr; }
//分区判断 public List<PartitionInfo> isHasPart(){ //查询所有的分区 String partSql = "SELECT PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME='TM_BUS_WARN_MESSAGE_HIS'"; //集合list List<PartitionInfo> partList = new ArrayList<PartitionInfo>(); partList = jdbcTemplate.query(partSql,new PartitionInfoMapper()); return partList ; } /** * 分区Mapper * @author han */ class PartitionInfoMapper implements RowMapper<PartitionInfo>{ public PartitionInfo mapRow(ResultSet rs, int rn) throws SQLException { PartitionInfo partBean = new PartitionInfo(); partBean.setPartitionName(rs.getString("PARTITION_NAME")); return partBean; } }
4 注意。需要注意2点,第一个就是如果之后再增加新的分区,代码可以不用修改,直接可以用。就是在写代码的时候,尽量用动态的参数,不要写死。第二个就是由于flex是异步执行的,看下图所示:
结束。