RO20 –
如何使用
DataSnap
类创建服务
本文说明如果使用
DataSnap
类从远处客户端获取数据
,
并将最后的修改保存回数据库
.
范例项目提供的下载地址在文档结束处
.
打开
CDSServerSample.bpg
项目组
.
注意
:
如果你在自己的系统中验证这个项目你将会从本文中得到很多经验
,
但是不去验证也可以获取一些合理的想法
.
服务端
服务端有主窗体和实现
CDSService
服务的
Data Module
组成
.
CDSService
服务定义如下
:
ICDSService = interface
[
'{1F0A5C88-4B51-4D74-B2A9-C850E25E309A}'
]
function GetData: Binary;
procedure UpdateData(const Delta: Binary);
end
;
GetData
方法将从
DBDEMOS
表
"employee.db"
中读取所有数据
,
转换成为二进制流传送到客户端的
TClientDataset. TClientDataset
绑定在
TDBGrid
上
,
可以无连接浏览和编辑数据
.
UpdataData
方法将客户端修改的数据传回服务端并保存回数据表
"employee.db".
如果方法失败不做任何存储并向客户端传递一个异常
.
包含在
CDSService_Impl.pas
单元的数据模块如下图
:
可见数据模块中除了
DataSetProvider
控件外没有其他特殊的了
.
这个控件在
GetData
方法中负责生成返回数据并在
UpdateData
中负责处理修改的内容
.
这是
TCDSService
的
GetData
方法的实现
:
function
TCDSService.GetData: Binary;
var
recsout: integer;
begin
result := BinaryFromVariant(
DataSetProvider.GetRecords(-
1
, recsout, MetaDataOption + ResetOption));
end
;
BinaryFromVariant
是在
uROBinaryHelpers.pas
单元中提供的使用函数
.
简单的将
OleVariants
转换成
Binary(
二进制
TMemoryStream).
在
Delphi
的帮助文件中查看
TDatasetProvider.GetRecords
方法
.
这是
UpdateData
方法的实现
:
procedure
TCDSService.UpdateData(const Delta: Binary);
var
errcnt: integer;
begin
DataSetProvider.ApplyUpdates(VariantFromBinary(Delta),
0
, errcnt);
if (errcnt>
0
) then
raise
Exception.CreateFmt(
'There were %d errors'
, [errcnt]);
end
;
使用
VariantFromBinary
将保存数据变化的
Delta
转变为
Variant
类型
,
在调用
DataSetProvider
的方法保存修改
.
服务端就这些
.
客户端
客户端如下图
:
如下是
"Get Data"
按钮的处理事件
:
procedure
TClientForm.Button1Click(Sender: TObject);
var
svc: CDSService;
data: Binary;
begin
svc := CoCDSService.Create(ROSOAPMessage, ROWinInetHTTPChannel1);
try
data := svc.GetData;
ClientDataSet1.Data := VariantFromBinary(data);
finally
data.Free;
end;
end
;
第一行创建远程服务代理
,
然后调用
GetData
方法
,
使用
uROBinaryHelpers.pas
中的函数
VariantFromBinary
转换数据格式
,
在给
TClientDataset.Data
赋值
.
当方法执行后我们发现
TDBGrid
中显示了远程
"employee.db"
表的所有数据
.
下面是
"Update Data"
按钮的事件处理代码
:
procedure
TClientForm.Button2Click(Sender: TObject);
var
svc: CDSService;
delta: Binary;
begin
if
(ClientDataSet1.ChangeCount=
0
) then begin
MessageDlg(
'There are no changes pending'
, mtError, [mbOK],
0
);
Exit;
end;
delta := NIL ;
try
delta := BinaryFromVariant(ClientDataSet1.Delta);
svc := CoCDSService.Create(ROSOAPMessage, ROWinInetHTTPChannel1);
svc.UpdateData(delta);
finally
delta.Free;
end;
end
;
结论
这个范例向你展示使用
RO
和
DataSnap
类创建系统是多么的方便
.
随
RemObjects SDK
一同发布的
DataSnap
综合包简化了处理过程
,
并运行不写任何代码就能创建一个成熟的
DataSnap
应用程序
.