做了一个前台使用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 partBeanList = new ArrayList();
partBeanList = queryAlermDetailInfoDao.isHasPart();
List partNameStrList = new ArrayList();
PartitionInfo po = new PartitionInfo();
for(int i=0;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 isHasPart(){
//查询所有的分区
String partSql = "SELECT PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME='TM_BUS_WARN_MESSAGE_HIS'";
//集合list
List partList = new ArrayList();
partList = jdbcTemplate.query(partSql,new PartitionInfoMapper());
return partList ;
}
/**
* 分区Mapper
* @author han
*/
class PartitionInfoMapper implements RowMapper{
public PartitionInfo mapRow(ResultSet rs, int rn)
throws SQLException {
PartitionInfo partBean = new PartitionInfo();
partBean.setPartitionName(rs.getString("PARTITION_NAME"));
return partBean;
}
}
4 注意。需要注意2点,第一个就是如果之后再增加新的分区,代码可以不用修改,直接可以用。就是在写代码的时候,尽量用动态的参数,不要写死。第二个就是由于flex是异步执行的,看下图所示:
结束。