Delphi三层开发小技巧:TClientDataSet的Delta妙用

转载 2014年10月13日 09:41:14
  • 318

from :
http://www.cnblogs.com/fyen/archive/2011/04/21/2023223.html

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这个方法,返回各自的表名,其他的一句代码都不用写.

Delphi三层开发小技巧:TClientDataSet的Delta妙用的更多相关文章

  1. Windows统一平台: 开发小技巧

    Windows统一平台: 开发小技巧 技巧一: 在手机端拓展你应用的显示区域.(WP8.1中也适用) 对于Windows Phone系统的手机, 手机屏幕最上方为系统状态栏(System Tray), ...

  2. flex开发小技巧集锦

    关于flex开发网上有非常多的相关信息介绍,因此我们要想学习关于flex开发的知识信息技能是一件非常简单和方便的事情.而针对于flex开发小编要告诉大家的是一些flex开发小技巧.利用这些小技巧能够有 ...

  3. TP开发小技巧

    TP开发小技巧原文地址http://wp.chenyuanzhao.com/wp/2016/07/23/tp%E5%BC%80%E5%8F%91%E5%B0%8F%E6%8A%80%E5%B7%A7/ ...

  4. 移动Web开发小技巧

    移动Web开发小技巧 添加到主屏后的标题(IOS) name="apple-mobile-web-app-title" content="标题"> 启用  ...

  5. BizTalk开发小技巧

    BizTalk开发小技巧 随笔分类 - Biztalk Biztalk 使用BizTalk实现RosettaNet B2B So Easy 摘要: 使用BizTalk实现RosettaNet B2B ...

  6. Java开发小技巧(三):Maven多工程依赖项目

    前言 本篇文章基于Java开发小技巧(二):自定义Maven依赖中创建的父工程project-monitor实现,运用我们自定义的依赖包进行多工程依赖项目的开发. 下面以多可执行Jar包项目的开发为例 ...

  7. iOS开发小技巧 - UILabel添加中划线

    iOS开发小技巧 遇到的问题: 给Label添加中划线,然后并没有效果 NSString *str = [NSString stringWithFormat:@"合计金额 ¥%.2f&quo ...

  8. PHP开发小技巧②—实现二维数组根据key进行排序

    在PHP中内置了很多对数组进行处理的函数,有很多时候我们直接使用其内置函数就能达到我们的需求,得到我们所想要的结果:但是,有的时候我们却不能通过使用内置函数实现我们的要求,这就需要我们自己去编写算法来 ...

  9. PHP开发小技巧③—实现多维数组转化为一维数组

    在平常的项目开发中我们多会用到让多维数组转化为一维数组的情况,但是很多Programmer不会将其进行转化,也有些没有想到很好的算法然后经过乱起八糟的运算方式将其勉强转化好,但是所写的程序代码冗余非常 ...

随机推荐

  1. ios 视图切换翻页效果

    本文写的是视图切换,涉及到的内容有 1.实现代码添加Navigation Bar  Toolbal: 2.实现在Navigation Bar和Toolbar上用代码添加Bar Button Item: ...

  2. for(j=0,i=0;j

    for(j=0,i=0;j<6,i<10;j++,i++) { k=i+j; } k 值最后是多少? <script type="text/javascript" ...

  3. CH1801 括号画家

    题意 Candela是一名漫画家,她有一个奇特的爱好,就是在纸上画括号.这一天,刚刚起床的Candela画了一排括号序列,其中包含小括号( ).中括号[ ]和大括号{ },总长度为N.这排随意绘制的括 ...

  4. 40+个对初学者非常有用的PHP技巧

    1.不要使用相对路径,要定义一个根路径 这样的代码行很常见: require_once('../../lib/some_class.php'); 这种方法有很多缺点: 它首先搜索php包括路径中的指定 ...

  5. 异常处理—Exception(三)

    最近有点事,把这个系列给落下了,给大家道个歉,这里还要感谢我的老婆,谢谢她一直对我的支持:) 系列回顾: 1.异常处理--Exception(一) 2.异常处理—Exception(二) 上一篇中主要 ...

  6. jQuery 性能优化技巧

    原文地址:jQuery 性能优化技巧 博客地址:http://www.extlight.com 一.使用最新版本 jQuery 类库 二.合理使用选择器 # 推荐使用 $("#id" ...

  7. Renesas 符号地址空间对齐

    对齐方式定义头文件:bsp_compiler_support.h #define BSP_SECTION_STACK ".stack" #define BSP_SECTION_HE ...

  8. (转)Inno Setup入门(六)——在程序目录下创建文件夹

    本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17250789 创建文件夹可以使用[dirs]段实现,代码如下: [s ...

  9. Firewalld中的whitelist并不是规则白名单

    原文地址:http://www.excelib.com/article/292/show whitelist的含义 白名单跟防火墙结合在一起大家很容易将其理解为规则白名单,不过在Firewalld中w ...

  10. 【转】挟天子以令诸侯博客关于TCP/IP模型与OSI模型的区别

    挟天子以令诸侯 博客园 首页 新随笔 联系 订阅 管理 随笔 - 21  文章 - 0  评论 - 9 TCP/IP四层模型与OSI参考模型   TCP/IP四层模型: 1.链路层(数据链路层/网络接 ...