做了一個前台使用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是異步執行的,看下圖所示:

結束。