Refresh清除本记录所有的变更记录,并将数据库中的值作为当前记录的值.Merge试图将数据库
记录和更新记录合并.将变更提交到数据库.更新和合并的记录都不会再进行处理,记录已经与数 据库同步.
Correct是一个强大的选项,在事件处理中给你一个指定更新记录值的机会.需要写代码或弹出 对话框指定新值.
3.3. DATASNAP 数据库部署
部署一个使用数据库的DataSnap服务需要比部署一个简单DataSnap服务的步骤要多些.客户端,
没什么变化,还是一个瘦客户端,如将MidasLib加入到了项目引用就仅需部署一个单一的可执行文 件.
服务端,必须部署数据库驱动.及所选数据库依赖的驱动和文件.使用DBX4,确保发布
TSQLConnection组件和dbxconnections.ini及dbxgrivers.ini文件(可在C:\\Documents and
Settings\\All Users\\ Documents\\RAD
Studio\\dbExpress\\7.0 directory on Windows XP or in the C:\\Users\\Public\\Documents\\RAD
Studio\\dbExpress\\7.0中找到). dbxdrivers.ini文件指定所用驱动, DriverPackageLoader及
MetaDataPackageLoader(通常指向同一个包).对于BlackFishSQL,使用的DBXClientDriver140.bpl文件,需要
部署到服务端.更多关于部署BlashFishSQL信息见RAD Studio\\7.0 目录下的deploy_en.htm文件.
3.4. 重用已有的远程数据模块
如果你有一个远程数据模块类,也可以将其组合到新的DataSnap项目中来.但是必须要牺牲一些特性,尤其 是引入了COM.
首先,如果有一个你要迁移的DataSnap服务应用程序,而不仅仅是一个远程数据模块,你需要使用命令行
/unregister注销DataSnap服务.不做这步将无法注销远程数据模块.在远程数据模块单元,移除initialization区
域.如果还希望这个单元在D2007及一下版本重用,可以使用编译开关: {$IF CompilerVersion >= 20} initialization
TComponentFactory.Create(ComServer, TRemoteDataModule2010, Class_RemoteDataModule2010, ciMultiInstance, tmApartment); {$IFEND} end.
从项目中移除UpdateRegistry函数或用编译开关修饰: {$IF CompilerVersion >= 20}
class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override; {$IFEND}
最重要的变更—将项目转换为无COM依赖的DataSnap服务.-及移除类型库(.ridl文件)和类型库导入单元.这
无法通过编译器开关修改,因此需要为D2007及一下版本和D2009及以上版本分别生成一个项目文件.在
TRemoteDataModule类中放一个TDSServerClass组件.最后,将所有的自定义方法都转到
TRemoteDataModule单元的public节中. 4. DATASNAP 过滤器[FILTER]用法
本节将说明过滤器工作原理,及如何使用已存在的过滤器(如压缩)或创建新的DataSnap过滤器.DataSnap
过滤器是一个特殊的DLL,拦截通讯流,在整个过滤器链中操作通讯流.所以本例中我们可以使用压缩和解压缩 过滤器,或记录压缩等.
必须在客户端和服务端指定过滤器.在服务端,必须指定TDSTCPServerTransport组件的过滤器属性列表.
在客户端,必须在客户端项目中引用过滤器单元文件.对于客户端这就足够了,因为每个DataSnap过滤器都会 自动注册.
当处理OnConnect事件时,可以检查用于连接的已注册的过滤器,例如使用自定义的日志函数输入日志信息,
procedure TServerContainer1.DSServer1Connect( DSConnectEventObject: TDSConnectEventObject); var
i: Integer; begin
LogInfo('Connect ' + DSConnectEventObject.ChannelInfo.Info); for i:=0 to DSConnectEventObject.Transport.Filters.Count-1 do LogInfo(' Filter: ' +
DSConnectEventObject.Transport.Filters.GetFilter(i).Id); end;
4.1. ZLIBCOMPRESSION FILTER
作为范例,我们使用已随D2010提供的DataSnap过滤器.可用于在客户端和服务端压缩数据流.这里说的
ZlibCompression过滤器可以在DbxCompressionFilter单元找到.
TDSTCPServer和TDSHTTPService组件都有一个TTransportFiltersCollection类型的Filters属性.点击Filters
属性后面的按钮,编辑过滤器列表.在这个对话框中,我们可以加一个新的TTransportFilterItem,然后在Object
Inspector中设置FilterID和一些属性.在下拉框中可以找到Delphi2010提供的ZLibCompression过滤器.
注意除了设置服务端TDSTCPServerTransport组件Filters属性外,也需要在客户端指定一个相应的过滤器
(压缩请求解压缩应答).这时,我们进需要将DbxCompressionFilter单元引用到ClientForm.其将自动注册一个
TTransportCompressionFilter并与服务端通讯.
如果没有在客户端添加DbxCompressionFilter单元引用,运行客户端后将会抛出异常信息:
4.2. LOG FILTER
Delphi 2010 DataSnap 允许自定义传输过滤器.我们可以从TTransportFilter 类型继承自己的类.在这个新
类中,可以重写基类中的方法,实现这些方法.例如我们创建一个TLogFilter类: unit LogFilter; interface uses
SysUtils, DBXPlatform, DBXTransport; type
TLogFilter = class(TTransportFilter) ; private protected
function GetParameters: TDBXStringArray; override; function GetUserParameters: TDBXStringArray; override; public
function GetParameterValue(const ParamName: UnicodeString): UnicodeString; override;
function SetParameterValue(const ParamName: UnicodeString; const ParamValue: UnicodeString): Boolean; override; constructor Create; override; destructor Destroy; override;
function ProcessInput(const Data: TBytes): TBytes; override; function ProcessOutput(const Data: TBytes): TBytes; override; function Id: UnicodeString; override;
end; const
LogFilterName = 'Log'
这个类的很多方法实现都是空的:由于仅仅用于记录ProcessInput和ProcessOutput方法传输的数据,很多方 法都不用实现.非空方法如下:
function TLogFilter.SetParameterValue(const ParamName, ParamValue: UnicodeString): Boolean; begin
Result := True; end;
constructor TLogFilter.Create; begin
inherited Create; end;
destructor TLogFilter.Destroy; begin
inherited Destroy; end;
function TLogFilter.ProcessInput(const Data: TBytes): TBytes; begin
Result := Data; // log incoming data end;
function TLogFilter.ProcessOutput(const Data: TBytes): TBytes;