ADOQuery代替ClientDataSet做3-Tier系统
生活随笔
收集整理的這篇文章主要介紹了
ADOQuery代替ClientDataSet做3-Tier系统
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
| ADOQuery代替ClientDataSet做3-Tier系統(tǒng) |
| 2005-09-06 13:41:00 |
| 3-Tier的系統(tǒng)我們一般用Midas的TClientDataSet,它搭配BDE的TQuery效率還可以,畢竟是一家的;但搭配TADOQuery就慢了很多,大概9倍,因?yàn)椴粫缘萌思业馁Y料存儲(chǔ)格式,只能一個(gè)Field一個(gè)Field讀出來(lái)再用TDataSetProvider打包成Data:OLEVariant; ADO2.5提供了一個(gè)_Stream組件,配合BatchUpdate,可以做到TClientDataSet的功能,它的效率可以達(dá)到與TClientDataSet+TQuery一樣: 1.Client給SQL到Server,Server用TADOQuery獲取資料,然后Save到_Stream,返回; 2.Client用_Stream接收Server返回資料,給TADOQuery,用戶可以隨意增/刪/改; 3.Client把用戶修改后的資料Save到_Stream,傳給Server(我現(xiàn)在還沒(méi)辦法只把異動(dòng)資料存到_Stream,它把沒(méi)有修改的資料也Save進(jìn)去了,因?yàn)樵赪AN上跑時(shí)資料量對(duì)效率影響大;一種方法是存為XML格式,再用XML?DOM組件去解析,把沒(méi)修改的資料刪掉,看各位還有更好的方法沒(méi)有?); 4.Server用_Stream接收Client的修改資料,給TADOQuery,把FilterGroup設(shè)為fgPendingRecords,可以分析資料的增/刪/改情況,處理企業(yè)邏輯,最后調(diào)用UpdateBatch保存資料。 5.Client在Call?Server保存成功后,也調(diào)用UpdateBatch,使資料與實(shí)際一致,因?yàn)門ADOQuery沒(méi)有聯(lián)接Connection,因此UpdateBatch相當(dāng)于TClientDataSet的ClearChangeLog? Server端的代碼(Com+): ? function?TEOStudent.ReadADOData(const?ASQL:?WideString):?OLEVariant; var ??AStream:_Stream; ??MS1:TMemoryStream; ??V:OLEVariant; ??P:Pointer; begin ??try ????ADOConnection.Close; ????ADOQuery.Close; ????ADOQuery.SQL.Text:=ASQL; ????ADOQuery.Open; ????AStream:=CoStream.Create; ????OLEVariant(ADOQuery.Recordset).Save(AStream,adPersistADTG); ????ADOQuery.Close; ????AStream.Position:=0; ????V:=AStream.Read(AStream.Size); ????MS1:=TMemoryStream.Create; ????try ??????P:=VarArrayLock(V); ??????try ????????MS1.Size:=VarArrayHighBound(V,1)+1; ????????Move(P^,MS1.Memory^,MS1.Size); ??????finally ????????VarArrayUnLock(V); ??????end; ??????Result:=VarArrayCreate([0,MS1.Size-1],varByte); ??????P:=VarArrayLock(Result); ??????try ????????Move(MS1.Memory^,P^,MS1.Size); ??????finally ????????VarArrayUnLock(Result); ??????end; ????finally ??????MS1.Free; ????end; ????SetComplete; ??except ????SetAbort; ????Raise; ??end; end; ? procedure?TEOStudent.SaveADOData(AData:?OLEVariant); var ??AStream:_Stream; ??AR:_Recordset; begin ??try ????ADOQuery.Close; ????AStream:=CoStream.Create; ????AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified,?‘‘,?‘‘); ????AStream.Type_:=adTypeBinary; ????AStream.Write(AData); ????AStream.Position:=0; ????AR:=_Recordset(CoRecordset.Create); ????AStream.Position:=0; ????AR.Open(AStream,EmptyParam,adOpenKeyset,adLockBatchOptimistic,0); ????ADOConnection.Close; ????ADOConnection.Open; ????AR.Set_ActiveConnection(ADOConnection.ConnectionObject); ????ADOQuery.Recordset:=ADOInt._Recordset(AR); {????ADOQuery.FilterGroup:=fgPendingRecords; ????ADOQuery.Filtered:=true; ????try ??????ADOQuery.First; ??????while?not?ADOQuery.Eof?do ??????begin ????????case?ADOQuery.UpdateStatus?of ??????????usModified:ShowMessage( ??VarToStr(ADOQuery.FieldByName(‘SeqNo‘).OldValue)+‘:‘+ ??ADOQuery.FieldByName(‘SeqNo‘).asString); ????????end; ????????ADOQuery.Next; ??????end; ????finally ??????ADOQuery.Filtered:=false;?//stateless ????end;} ????ADOQuery.UpdateBatch; ????ADOConnection.Close; ????SetComplete; ??except ????SetAbort; ????Raise; ??end; end; Client端,Form上放一個(gè)TADOQuery,不用連接Connection: ? 獲取資料 procedure?TForm1.Button5Click(Sender:?TObject); var ??V:OLEVariant; ??AR:_Recordset; ??AStream:_Stream; ??MS1:TMemoryStream; ??P:Pointer; ??s:string; begin ??DCOM.Connected:=true; ??try ????s:=‘‘; ????V:=DCOM.AppServer.ReadADOData(‘select?*?from?FORMDD‘); ????MS1:=TMemoryStream.Create; ????try ??????MS1.Size:=VarArrayHighBound(V,1)+1; ??????P:=VarArrayLock(V); ??????try ????????Move(P^,MS1.Memory^,MS1.Size); ??????finally ????????VarArrayUnLock(V); ??????end; ??????V:=VarArrayCreate([0,MS1.Size-1],varByte); ??????P:=VarArrayLock(V); ??????try ????????Move(MS1.Memory^,P^,MS1.Size); ??????finally ????????VarArrayUnLock(V); ??????end; ????finally ??????MS1.Free; ????end; ????AStream:=CoStream.Create; ????AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified,?‘‘,?‘‘); ????AStream.Type_:=adTypeBinary; ????AStream.Write(V); ? ????AR:=_Recordset(CoRecordset.Create); ????AStream.Position:=0; ????AR.Open(AStream,EmptyParam,adOpenUnspecified,?adLockUnspecified,?-1); ????ADOQuery1.Recordset:=ADOInt._Recordset(AR); ??finally ????DCOM.Connected:=false; ??end; end; ? //保存資料 procedure?TForm1.Button6Click(Sender:?TObject); var ??AStream:_Stream; ??V:OLEVariant; begin ??DCOM.Connected:=true; ??try ????ADOQuery1.CheckBrowseMode; ????AStream:=CoStream.Create; ????OLEVariant(ADOQuery1.Recordset).Save(AStream,adPersistADTG); ????AStream.Position:=0; ????V:=AStream.Read(AStream.Size); ????DCOM.AppServer.SaveADOData(V); ????ADOQuery1.UpdateBatch;??//no?connection,means?clearchangelog ??finally ????DCOM.Connected:=false; ??end; end; ? |
轉(zhuǎn)載于:https://www.cnblogs.com/fuyingke/archive/2005/10/14/254669.html
總結(jié)
以上是生活随笔為你收集整理的ADOQuery代替ClientDataSet做3-Tier系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 只要用心就可以看见 十个幸福瞬间照片
- 下一篇: ASP.NET程序中常用代码汇总(四)