日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Delphi三層開發(fā)小技巧:TClientDataSet的Delta妙用

 aaie_ 2011-11-23
Delphi做三層開發(fā)時(shí),很多人都會在客戶端放一個(gè)TClientDataSet,中間層遠(yuǎn)程數(shù)據(jù)模塊就對應(yīng)放一個(gè)TDataSetProvider, 然后再連起來.其實(shí)這種方法很煩瑣,而且程序癰腫不甘,不好維護(hù).我們都知道TClientDataSet的Delta屬性記錄了數(shù)據(jù)的所有修改,應(yīng)用它我們就可以方便的實(shí)現(xiàn)一個(gè)單表更新的通用方法.

   首先,在中間層添加一個(gè)方法,就叫ApplyUpdates吧.方法定義如下:

   function ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;

參數(shù)UpdateTable是指要更新的表名,Delta是指傳過來的TClientDataSet的Delta屬性,如果更新錯(cuò)誤err返回錯(cuò)誤的內(nèi)容.下面實(shí)現(xiàn)這個(gè)方法,首先在DataModule上放一個(gè)Query,Query連上Connection,然后再放一個(gè) TDataSetProvider連Query.代碼如下:

01 function TRoDm.ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;
02   
03 const sql='select * from %s where 1<>1';
04   
05 var sqlstr:string;
06   
07       ErrCount:Integer;
08   
09 begin
10   
11     Result:=False;
12   
13    sqlstr:=Format(sql,[UpdateTable]);
14   
15    try
16   
17        Conn.BeginTrans;
18   
19        Query.Close;
20   
21        Query.sql.text:=sqlstr;
22   
23        Query.open;
24   
25       Provider.ApplyUpdates(Delta,-1,ErrCount);
26   
27       Result:=ErrCount=0;
28   
29       if Result then
30   
31          Conn.CommitTrans
32   
33       else Conn.RollbackTrans;
34   
35    except
36   
37        on E:Exception do
38   
39        begin
40   
41            Conn.RollbackTrans;
42   
43           err:=E.Message;
44   
45        end;
46   
47    end;
48   
49 end;

    到此,通用的更新方法已經(jīng)完成了.不過客戶端的ClientDataSet還不能查詢顯示數(shù)據(jù),因此,還要寫一個(gè)查詢方法:

    function QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;

    參數(shù)sqlstr就是要持行的查詢語句,Data返回查詢結(jié)果,錯(cuò)誤時(shí)err返回錯(cuò)誤消息

   QuerySQL實(shí)現(xiàn)代碼如下:

01 function TRoDm.QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;
02   
03 begin
04   
05     Result:=False;
06   
07    try
08   
09       Query.close;
10   
11       Query.sql.text:=sqlstr;
12   
13         Query.sql.Open;
14   
15         Data:=Provider.Data;
16   
17        Result:=True;
18   
19     Except
20   
21          on E:Exception do
22   
23              err:=E.Message;
24   
25     end;
26   
27 end;

    到這里,中間層的代碼已經(jīng)完了,客戶端的調(diào)用就簡單了.比如客戶端有個(gè)數(shù)據(jù)模塊DM,上面放一個(gè)DcomConnection或者 SocketConnection,名叫Conn.例如,我們現(xiàn)在要做一個(gè)商品管理的功能,在窗體上放一個(gè)TClientDataSet叫Cds,放 DataSource,DBGrid等,設(shè)置好相應(yīng)的屬性.然后在窗體創(chuàng)建(Create事件)時(shí)查詢回所有數(shù)據(jù),代碼如下:

01 const sql='select * from xxxx';
02   
03 var Data:Variant;
04   
05       err:String;
06   
07 begin
08   
09    if Dm.Conn.AppServer.QuerySQL(sql,Data,err) then
10   
11       Cds.Data:=Data
12   
13    else MessageBox(self.handle,pchar('查詢數(shù)據(jù)出錯(cuò):'+err),'錯(cuò)誤',MB_OK+MB_ICONERROR);      
14   
15 end;
16   
17    然后還有"添加","修改","刪除"按扭,代碼都和我們平時(shí)操作一樣,比如"添加"按扭的代碼:
18   
19    cds.append;
20   
21    cds.fieldbyname('xxx').asinteger:=xxx;
22   
23    //....
24   
25    cds.post;

    修改,刪除也這樣寫.不過現(xiàn)在還有個(gè)小問題是,這個(gè)表的主鍵的生成問題,這里我們不能用自增主鍵,要自己自己生成主鍵,這樣你還得在中間層寫一個(gè)中間層生成主鍵的方法,在"增加"按扭時(shí)生調(diào)用生成主鍵,然后再上面的操作.這里不再多說.

    增刪改完后,這時(shí)的數(shù)據(jù)還在客戶端的內(nèi)存里,想保存到遠(yuǎn)程的中間層服務(wù)器就要用到我們剛才的方法了,下面就是"保存"按扭下的代碼:

01 var err:string;
02   
03 begin
04   
05     if cds.ChangeCount=0 then exit;//數(shù)據(jù)沒改變就不用提交了
06   
07     if Dm.Conn.AppServer.ApplyUpdates('xxx',cds.Delta,err) then//xxx就是表名了
08   
09     begin
10   
11        MessageBox(self.handle,'保存成功!','提示',MB_OK+MB_ICONINFORMATION);
12   
13         cds.MergeChangeLog;//合并所有改變的數(shù)據(jù)
14   
15     end else MessageBox(self.handle,pchar('保存出錯(cuò):'+err),'錯(cuò)誤',MB_OK+MB_ICONERROR);
16   
17 end;

   到此,這篇文章也講完了.用這個(gè)方法,那些單表的基礎(chǔ)數(shù)據(jù)更新還可以寫成一個(gè)祖先類,只要加一個(gè)取得更新表名的虛方法,比如:function TableName:string;virtual;然后其后代只要override這個(gè)方法,返回各自的表名,其他的一句代碼都不用寫.

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多