Delphi三层开发小技巧:TClientDataSet的Delta妙用
Delphi三層開發小技巧:TClientDataSet的Delta妙用
?
Delphi做三層開發時,很多人都會在客戶端放一個TClientDataSet,中間層遠程數據模塊就對應放一個TDataSetProvider,然后再連起來.其實這種方法很煩瑣,而且程序很繁瑣,不好維護.我們都知道TClientDataSet的Delta屬性記錄了數據的所有修改,應用它我們就可以方便的實現一個單表更新的通用方法.
?? 首先,在中間層添加一個方法,就叫ApplyUpdates吧.方法定義如下:
?? function ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;
參數UpdateTable是指要更新的表名,Delta是指傳過來的TClientDataSet的Delta屬性,如果更新錯誤err返回錯誤的內容.下面實現這個方法,首先在DataModule上放一個Query,Query連上Connection,然后再放一個TDataSetProvider連Query.代碼如下:
function TRoDm.ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;
const sql='select * from %s where 1<>1';
var sqlstr:string;
????? ErrCount:Integer;
begin
??? Result:=False;
?? sqlstr:=Format(sql,[UpdateTable]);
?? try
?????? Conn.BeginTrans;
??? ???Query.Close;
?????? Query.sql.text:=sqlstr;
?????? Query.open;
????? Provider.ApplyUpdates(Delta,-1,ErrCount);
????? Result:=ErrCount=0;
????? if Result then
???????? Conn.CommitTrans
????? else Conn.RollbackTrans;
?? except
?????? on E:Exception do
?? ????begin
?????????? Conn.RollbackTrans;
????????? err:=E.Message;
?????? end;
?? end;
end;
??? 到此,通用的更新方法已經完成了.不過客戶端的ClientDataSet還不能查詢顯示數據,因此,還要寫一個查詢方法:
??? function QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;
??? 參數sqlstr就是要持行的查詢語句,Data返回查詢結果,錯誤時err返回錯誤消息
?? QuerySQL實現代碼如下:
function TRoDm.QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;
begin
??? Result:=False;
?? try
????? Query.close;
????? Query.sql.text:=sqlstr;
??????? Query.sql.Open;
??????? Data:=Provider.Data;
?????? Result:=True;
??? Except
???????? on E:Exception do
???????????? err:=E.Message;
??? end;
end;
??? 到這里,中間層的代碼已經完了,客戶端的調用就簡單了.比如客戶端有個數據模塊DM,上面放一個DcomConnection或者SocketConnection,名叫Conn.例如,我們現在要做一個商品管理的功能,在窗體上放一個TClientDataSet叫Cds,放DataSource,DBGrid等,設置好相應的屬性.然后在窗體創建(Create事件)時查詢回所有數據,代碼如下:
const sql='select * from xxxx';
var Data:Variant;
????? err:String;
begin
?? if Dm.Conn.AppServer.QuerySQL(sql,Data,err) then
????? Cds.Data:=Data
?? else MessageBox(self.handle,pchar('查詢數據出錯:'+err),'錯誤',MB_OK+MB_ICONERROR);?????
end;
?? 然后還有"添加","修改","刪除"按扭,代碼都和我們平時操作一樣,比如"添加"按扭的代碼:
?? cds.append;
?? cds.fieldbyname('xxx').asinteger:=xxx;
?? //....
?? cds.post;
??? 修改,刪除也這樣寫.不過現在還有個小問題是,這個表的主鍵的生成問題,這里我們不能用自增主鍵,要自己自己生成主鍵,這樣你還得在中間層寫一個中間層生成主鍵的方法,在"增加"按扭時生調用生成主鍵,然后再上面的操作.這里不再多說.
??? 增刪改完后,這時的數據還在客戶端的內存里,想保存到遠程的中間層服務器就要用到我們剛才的方法了,下面就是"保存"按扭下的代碼:
var err:string;
begin
??? if cds.ChangeCount=0 then exit;//數據沒改變就不用提交了
??? if Dm.Conn.AppServer.ApplyUpdates('xxx',cds.Delta,err) then//xxx就是表名了
?? ?begin
?????? MessageBox(self.handle,'保存成功!','提示',MB_OK+MB_ICONINFORMATION);
??????? cds.MergeChangeLog;//合并所有改變的數據
??? end else MessageBox(self.handle,pchar('保存出錯:'+err),'錯誤',MB_OK+MB_ICONERROR);
end;
?? 到此,這篇文章也講完了.用這個方法,那些單表的基礎數據更新還可以寫成一個祖先類,只要加一個取得更新表名的虛方法,比如:function TableName:string;virtual;然后其后代只要override這個方法,返回各自的表名,其他的一句代碼都不用寫.
scktsrvr.exe是一個NT的服務程序,你用scktsrvr.exe -install安裝之后,每次系統啟動,它都會自動運行的。如果你的客戶端用了socketconnection,每次連接應用服務器的時候,都需要通過scktsrvr.exe才能訪問到你的應用服務器.
scktsrvr.exe -uninstall 即可卸載
?
總結
以上是生活随笔為你收集整理的Delphi三层开发小技巧:TClientDataSet的Delta妙用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过崩溃地址找错误行数之Delphi版
- 下一篇: 在服务子程中首先关闭ie 的HTML5连