一種新的程式設計思路(上) (轉)

worldblog發表於2007-12-13
一種新的程式設計思路(上) (轉)[@more@]

一種新的思路(上):
  難得糊塗程式設計法 GBDP (適用、等程式設計)

GBDP技術實現設想:(General Blackbox Dynamic Programming)
  開發速度快、程式碼量少、通用,表自動生成,記錄自動增加,
  修改,刪除,設計工作量少,可以在需求不明確的情況下開工,
  漸進式開發,擁有需求頻繁更改、程式碼基本不動的自適應能力。特
  別適合國內亂序開發的國情

主要解決問題:
  系統設計工作量大,需求更改影響大,專案交接困難,程式設計風格各
  異,資料庫困難的問題

已經實現功能:
  資料表自動生成,記錄自動增加,修改,刪除,自動

GBDP功能示例:
  無須建表,不用關心表結構、欄位、值,儲存全部自動化,
  所有表結構統一使用id,pid,k,v四個欄位(int,int,varchar(255),
  varchar(255)) 自動事務處理
 
  create table ntTest(
  id  int  primary key ,
  pid  int  not null ,
  k  varchar(255)  not null , 
  v  varchar(255)  not null
  ) -- 和MS支援varchar到4000-8000
 
  因為的varchar(255)是最大長度。

  寫入資料庫和讀出資料到script使用了
  ntEncodeSimple和ntEncode的方法,否則特殊字元將導致錯誤

  指定submit的name為edit,add來控制動作方式,
  資料k(key)必須避開edit,add,submit,nouse等關鍵字

  必須使網頁元素的名稱和欄位名稱相同,形式由自動處理,
  不論text,radio,textarea
  例如: 意見:  未處理  同意 不同意 
  這3個radio的名稱都必須是"意見",然後值分別為"未處理 同意 不同意"


  以下是表中內容的示例:(id,pid , k , v)
  -8 1 意見  不同意
  -7 1 份數  1
  -6 1 公文種類  通知
  -3 1 印發時間  2002-05-10
  -2 1 保管期限  一年
  -1 1 發文日期  2002-05-10


資料增刪改頁面:



  局變數定義在ntGBDPDefine.jsp中
  globalTableName  = "xxx"; // 將自動生成此表,並建立提高速度
  parentKey  = "文章釋出";
  parentValue  = "";
  dbName  = "myDB";
  is  = true;  // 如果需要上傳,指定為true
%>

  if( isPost ){
  out.println("
  return;
  }
%>

…… 網頁部分開始……

form表單
  action=""
  onsubmit="return checkOnSubmit()" >

互動元件:
 
 
 
 
GBDP確認鈕 ,ok , 確定, 所有頁面統一使用
type="submit" name=""

id隱含,所有頁面統一使用,用於自動載入相關記錄
" value="" >

刪除顯示 修改頁面顯示“刪除”按鈕,用hasId判斷

 


  刪 除
 
 
 
 

 
…… 網頁部分結束……

以上是所有需要的程式碼,不用再寫任何其他的程式碼,就可以完成記錄
的增刪改等功能
----------------------------------------------------------------
下面查詢語句約2秒, 100萬/10萬記錄
  top 100 * from xxx_main
  where 1=1
  and pid =0 and k = '文章釋出' and v = ''
  and id in ( select pid from xxx_numeric
  where k='numeric數值測試' and v >= 131129 )
  and id in ( select pid from xxx_datetime
  where k='date日期測試' and v > '2002-01-02' )
  and id in ( select pid from xxx
  where k='秘密等級' and v = '秘密' )
  and id in ( select pid from xxx
  where k='緊急程度' and v = '一般' )
  order by id desc
----------------------------------------------------------------
所需檔案:
ntGBDPDefine.jsp

  意:本JSP被其他頁面,不能產生額外的空格和回車

  局變數定義
  String globalTableName ;
  String parentKey  ="" ;
  String parentValue ="" ;
  String dbName  = "e";
 
  ntDB ntP = new ntDB(); 
  ntDB nt  = new ntDB();
  String sql ;
 
  String sql_trans = "" ; 來插入後面的儲存到資料庫的sql語句中,使其中在事務之中間
  String sql_TRANS_ERROR = " if @@error<>0 set @ntE=@ntE+1 n";

  boolean isPost = false ;
  {
  isPost = request.getMethod().equals("POST");
  }
  boolean isEdit = false ;
  boolean isAdd  = false ;
  boolean isDelete = false ;
  boolean isUpload = false ;
  boolean hasId = false;
  boolean hasMasterId = false;
 
  int maxReturnRows = 1000 ;
  int id = 0 ; // 表示主記錄id號,一般為1,2,3......,必須在ntGBDPUpload.jsp
  //  中獲取,因為當upload的情況無法從request中獲取引數
  int masterId = 0 ; // 同上 , 用於主從表結構的實現
 
  對路徑
  String realPath ; // like 'c:a'
  {
  realPath = getConfig().getServletContext().getRealPath("");
  }
 
  動檔案上傳目錄指定
  String uploadDir;
  {
  uploadDir = realPath + "upload";
  }

  放所有request的資訊,使用它的原因是後面如果有upload的時候,
  //  request將沒有任何引數和值,必須從upload中重新找到
  java.util.Hashtable requestHt;
  {
  requestHt = new java.util.Hashtable();
  Enumeration e = request.getParameterNames();
  while( e.hasMoreElements() )
  {
  String s = (String)e.nextElement();
  String sValue = request.getParameter(s);
  requestHt.put( s , sValue );
  } 
  }
 
%>
----------------------------------------------------------------
所需檔案:
ntGBDPUpload2-1.jsp






傳檔案
if( isUpload && isPost )
{
  java.io.File mydir=new java.io.File( uploadDir ); is GlobalVar
  if( !mydir.exists() )
  if( !mydir.mkdir() )
  throw new Exception("建立上傳資料夾失敗![" + uploadDir + "]");

  SmartUpload mySmartUpload=new SmartUpload();
  mySmartUpload.initialize(pageContext);//初始化
  mySmartUpload.upload();//上傳
  Request res = mySmartUpload.getRequest();
  {
  request引數傳入requestHt全域性變數
  Enumeration e = res.getParameterNames();
  while( e.hasMoreElements() )
  {
  String s = ((String)e.nextElement()).trim();
  String sValue = (res.getParameter(s)).trim();
  requestHt.put( s , sValue );
  } 
  }
 
  Files files = mySmartUpload.getFiles();
  String ilename ="";
  for(int i=0;i com.jspsmart.upload.File file = files.getFile(i);
 sfilename = file.getFileName();
 //
 String s = sfilename ;
 if( !s.trim().equals("") )
  requestHt.put( "uploadFileName"+i , s );
  }

  try{
  mySmartUpload.save(uploadDir);
  }catch(Exception e){
  throw new Exception("上傳檔案失敗!"+ e.getMessage() );
  }

} // end if upload
%>

  isEdit = isPost && requestHt.get("edit")!=null ;
  isAdd  = isPost && requestHt.get("add")!=null  ;
  isDelete  = requestHt.get("delete")!=null ;
 
  // 這裡當沒有命令發出的時候,所有操作跳過
 
  hasId = requestHt.get("id")!=null ;
  id = 0 ;
  if( requestHt.get("id")!=null )
  id = Integer.parseInt( (String)requestHt.get("id") );
 
  hasMasterId = requestHt.get("mid")!=null ;
  masterId = 0 ;
  if( requestHt.get("mid")!=null )
  masterId = Integer.parseInt( (String)requestHt.get("mid") );

%>

  據檢查
%>

  查表是否存在,如果沒有,建5表, t_main , t, t_numeric, t_datetime, t_text
  sql = "";
  for(int i=0;i<5;i++){
  String sTableName = globalTableName ;
  String sType = "varchar(255)"; 
  if( i==1 )
  {  sTableName = globalTableName + "_numeric" ; sType = "numeric(38,8)" ;}
  else if( i==2 )
  {  sTableName = globalTableName + "_datetime"; sType = "datetime"; }
  else if( i==3 )
  {  sTableName = globalTableName + "_text"  ; sType = "text"; }
  else if( i==4 )
  {  sTableName = globalTableName + "_main"  ; }
 
  sql = sql +
  " if not exists( select name from syss  n"+
  "  where name ='"+ sTableName +"' and type='U' ) n"+
  " begin  n"+
  "  create table "+ sTableName +"(  n"+
  "  id  int  primary key  n"+
  "  , pid int  not null  n"+
  "  , v  "+ sType +"  not null  n"+
  "  , k  varchar(255) not null  n"+
  "  )  n"+
  " end n"+
  ""+
  " if not exists( select name from sysindexes  n"+
  "  where name like '%idx_"+ sTableName +"_pid%' ) n"+
  " begin  n"+
  "  create index idx_"+sTableName+"_pid on "+sTableName+"(pid) n"+
  " end n"+
  ""+
  " if not exists( select name from sysindexes  n"+
  "  where name like '%idx_"+ sTableName +"_k%' ) n"+
  " begin  n"+
  "  create index idx_"+sTableName+"_k on "+sTableName+"(k)  n"+
  " end n"+
  "";
 
  if( !sType.equals("text") ){
  sql = sql +
  " if not exists( select name from sysindexes  n"+
  "  where name like '%idx_"+ sTableName +"_v%' ) n"+
  " begin  n"+
  "  create index idx_"+sTableName+"_v on "+sTableName+"(v)  n"+
  " end n"+
  "";
  }
 
  sql = sql + "";
  } // end for create table 
  nt.executeUpdate(dbName,sql);
%>
----------------------------------------------------------------
所需檔案:
ntGBDPUpload2-2.jsp

  改
  if( isEdit &&  hasId )
  {
  //...
  查是否存在
  nt.executeQuery(dbName,
  "select * from "+ globalTableName +"_main where id = "+id );
  if( nt.rowCount <= 0 )
  throw new Exception("修改"+ globalTableName +"出錯:沒有找到id號'"+ id +"'");
  //
  sql = ""+
  " declare @i  int  n"+
  " declare @ntE int  n"+
  " select @ntE=0  n"+
  " begin tran  n"+
  " ";
 
  入額外需要在事務內的語句,共有3處加入, add, edit , delete
  sql_TRANS_ERROR = " if @@error<>0 set @ntE=@ntE+1 n";
  sql_trans = "" ; 來插入後面的儲存到資料庫的sql語句中,使其中在事務之中間
  if( sql_trans != null && !sql_trans.equals("") )
  sql = sql + sql_trans + sql_TRANS_ERROR;


  Enumeration er37 = requestHt.keys();
  while (er37.hasMoreElements()) {
  String s = ((String)er37.nextElement()).trim();
  String sValue = ((String)requestHt.get(s)).trim();
  if( sValue == null )
  sValue = "";
  sValue = nt.ntEncodeDB( sValue );
 
  String sTableName = globalTableName ;
  if( s.indexOf("numeric") == 0 )
  {  sTableName = globalTableName + "_numeric" ; }
  else if( s.indexOf("date") == 0 )
  {  sTableName = globalTableName + "_datetime";
  sValue = "'"+sValue+"'";
  }
  else if( s.indexOf("text") == 0 )
  {  sTableName = globalTableName + "_text"  ;
  sValue = "'"+sValue+"'";
  }
  else
  sValue = "'"+sValue+"'";
 
  須放在這裡,因為只有修改和增加數值型欄位才滿足sValue.equals("")
  if( sValue.equals("") )
  continue;
 
  if(  s.equals("edit")
  || s.equals("add")
  || s.equals("delete")
  || s.equals("id")
  || s.toLowerCase().indexOf("submit") >= 0
  || s.toLowerCase().indexOf("nouse") >= 0
  || s.toLowerCase().indexOf("useless") >= 0
  )
  {}
  else
  {
  sql = sql +
  " if exists ( select * from "+ sTableName +" where pid= "+ id +" and k='"+ s +"'" +" ) n"+
  "  begin  n"+
  "  update "+ sTableName +" set v = "+ sValue +"  n"+
  "  where pid= "+ id +" and k='"+ s +"'  n" +
  "  if @@error<>0  set @ntE=@ntE+1 n"+
  "  end  n"+
  " else  n"+
  "  begin  n"+
  "  select @i=@i "+
  "";
 
  if( !sValue.equals("") && !sValue.equals("''") )
  sql = sql +
  "  select @i = ( select isNull(min(id),0)-1 from "+ sTableName +" )  n"+
  "  if @i >= 0 select @i = -1 n"+
  "  insert into "+ sTableName +" (id,pid,k,v)  n"+
  "  values( @i, "+ id +  " n"+
  "  , '"+ s +"', "+ sValue +")  n"+
  "  if @@error<>0  set @ntE=@ntE+1 n"+
  "";

  sql = sql +
  " "+
  "  end  n"+
  " if @@error<>0  set @ntE=@ntE+1 n"+
  " ";
  }
  }//end while
  sql = sql +
  " if @ntE = 0  n"+
  "  commit tran  n"+
  " else  n"+
  "  begin  n"+
  "  rollback tran  n"+
  "  raiserror ('資料庫執行出錯! ',16,1)  n"+
  "  end  n"+
  " ";
 
  nt.executeUpdate( dbName,sql );
  } // end if edit
%>

  發文單新增儲存入資料庫
  if( isAdd )
  { // 隔離區域性變數
  rowNo  = -9999;
  formNo = -9999;
  file://nt.executeQuery(dbName,"select isNull(max(id),0)+1 from "+ globalTableName +"");
  = Integer.parseInt( nt.data[0][0] );
  file://nt.executeQuery(dbName,"select isNull(min(id),0)-1 from "+ globalTableName +"");
  = Integer.parseInt( nt.data[0][0] );

  sql = ""+
  " declare @ntE int n"+
  " declare @i  int n"+
  " declare @formNo int n"+
  " select @ntE=0  n"+
  " begin tran  n"+
  "";
 
  入額外需要在事務內執行的語句,共有3處加入, add, edit , delete
  sql_TRANS_ERROR = " if @@error<>0 set @ntE=@ntE+1 n";
  sql_trans = "" ; 來插入後面的儲存到資料庫的sql語句中,使其中在事務之中間
  if( sql_trans != null && !sql_trans.equals("") )
  sql = sql + sql_trans + sql_TRANS_ERROR;
 
 
  sql = sql +
  " select @i = ( select isNull(max(id),0)+1 from "+ globalTableName +"_main )  n"+
  " select @formNo = @i  n"+
  " insert into "+ globalTableName +"_main (id,pid,k,v) n"+
  "  values( @i, "+ (hasMasterId?masterId:0) +", '"+ parentKey +"', '"+ parentValue +"')  n"+
  "  if @@error<>0  set @ntE=@ntE+1 n"+
  " ";

  Enumeration er44 = requestHt.keys();
  while (er44.hasMoreElements()) {
  String s = ((String)er44.nextElement()).trim();
  String sValue = ((String)requestHt.get(s));
  if( sValue == null )
  sValue = "";
  sValue = sValue.trim();
 
  if( sValue.equals("") )
  continue;
 
  sValue = nt.ntEncodeDB( sValue );
  String sTableName = globalTableName ;
  if( s.indexOf("numeric") == 0 )
  {  sTableName = globalTableName + "_numeric" ; }
  else if( s.indexOf("date") == 0 )
  {  sTableName = globalTableName + "_datetime";
  sValue = "'"+sValue+"'";
  }
  else if( s.indexOf("text") == 0 )
  {  sTableName = globalTableName + "_text"  ;
  sValue = "'"+sValue+"'";
  }
  else
  sValue = "'"+sValue+"'";
 
  if(
  s.equals("edit")
  || s.equals("add")
  || s.equals("delete")
  || s.equals("id")
  || s.toLowerCase().indexOf("submit") >= 0
  || s.toLowerCase().indexOf("nouse") >= 0
  || s.toLowerCase().indexOf("useless") >= 0
  )
  {}
  else
  {
  sql = sql +
  " select @i = ( select isNull(min(id),0)-1 from "+ sTableName +" )  n"+
  " if @i >= 0 select @i = -1 n"+
  " insert into "+ sTableName +" (id,pid,k,v) "+
  "  values( @i, @formNo , '"+ s +"', "+ sValue +")  "+
  "  if @@error<>0  set @ntE=@ntE+1 "+
  " ";
  }
  }//end while
  sql = sql +
  " if @ntE = 0  "+
  "  commit tran  "+
  " else  "+
  "  begin  "+
  "  rollback tran  "+
  "  raiserror ('資料庫執行出錯!',16,1) "+
  "  end  "+
  " ";
  nt.executeUpdate( dbName,sql );

  } // 隔離區域性變數
%>

  pid 為 id 的刪除
  if( isDelete )
  { //
  查pid是否存在
  nt.executeQuery(dbName,"select * from "+ globalTableName +"_main where id = "+id );
  if( nt.rowCount <= 0 )
  throw new Exception("刪除"+ globalTableName +"出錯:沒有找到id號'"+ id +"'");

  sql = ""+
  " declare @ntE int n"+
  " declare @i  int n"+
  " select @ntE=0  n"+
  " begin tran  n"+
  "";
 
  入額外需要在事務內執行的語句,共有3處加入, add, edit , delete
  sql_TRANS_ERROR = " if @@error<>0 set @ntE=@ntE+1 n";
  sql_trans = "" ; 來插入後面的儲存到資料庫的sql語句中,使其中在事務之中間
  if( sql_trans != null && !sql_trans.equals("") )
  sql = sql + sql_trans + sql_TRANS_ERROR;
 
  sql = sql + 
  "  delete from "+ globalTableName +" where pid = "+ id + "n"+
  "  if @@error<>0 set @ntE=@ntE+1 n"+
  "  delete from "+ globalTableName +"_numeric where pid = "+ id + "n"+
  "  if @@error<>0 set @ntE=@ntE+1 n"+
  "  delete from "+ globalTableName +"_datetime where pid = "+ id + "n"+
  "  if @@error<>0 set @ntE=@ntE+1 n"+
  "  delete from "+ globalTableName +"_text where pid = "+ id + "n"+
  "  if @@error<>0 set @ntE=@ntE+1 n"+
  "  delete from "+ globalTableName +"_main where id = "+ id + "n"+
  "  if @@error<>0 set @ntE=@ntE+1 n"+
  " if @ntE = 0  n"+
  "  commit tran  n"+
  " else  n"+
  "  begin  n"+
  "  rollback tran  n"+
  "  raiserror ('資料庫執行出錯! ',16,1)  n"+
  "  end  n"+
  "";
  nt.executeUpdate(dbName, sql );

  } // 隔離區域性變數
%>
--------------------------------------------------------------
所需檔案:
ntGBDPScript.jsp

  GBDP方法通用模組
  本單元沒有采用的陣列,因為採用陣列後速度非常慢
--%>





  {

%>


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992887/,如需轉載,請註明出處,否則將追究法律責任。

相關文章