KbmMW本身可以用QueryService的方式进行远程数据查询,但是SmpileService同样具有很强的扩展性可以实现数据查询,下面展示两种基于SmpileService的远程数据查询方法,其原理都是利用TkbmMWSimpleService实现流的传输。

直接上代码了:

一、利用KbmMemTable:

  • 服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
unit unt_service_func;
 
// =========================================================================
// kbmMW - An advanced and extendable middleware framework.
// by Components4Developers (http://www.components4developers.com)
//
// Service generated by kbmMW service wizard.
//
// INSTRUCTIONS FOR REGISTRATION/USAGE
// -----------------------------------
// Please update the uses clause of the datamodule/form the TkbmMWServer is placed on by adding
// YourServiceUnitName to it. Eg.
//
//     uses ...,kbmMWServer,YourServiceUnitName;
//
// Somewhere in your application, make sure to register the serviceclass to the TkbmMWServer instance. Eg.
//
// var
//    sd:TkbmMWCustomServiceDefinition;
// ..
//    sd:=kbmMWServer1.RegisterService(yourserviceclassname,false);
//
// Set the last parameter to true if this is the default service.
//
 
{$I kbmMW.inc}
 
interface
 
uses
  SysUtils,
{$ifdef LEVEL6}
  Variants,
{$else}
  Forms,
{$endif}
  Classes,
  kbmMWSecurity,
  kbmMWServer,
  kbmMWServiceUtils,
  kbmMWGlobal,
  kbmMWADOX,DB, ADODB,kbmMemTable, kbmMemBinaryStreamFormat;
 
type
  TkbmMWSimpleService1 = class(TkbmMWSimpleService)
  private
     { Private declarations }
  protected
     { Protected declarations }
     //新增以下函数
     function ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; override;
     function PerformUpdate(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; virtual;
     function PerformSelect(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; virtual;
  public
     { Public declarations }
{$IFNDEF CPP}class{$ENDIF} function GetPrefServiceName:string; override;
{$IFNDEF CPP}class{$ENDIF} function GetVersion:string; override;
{$IFNDEF CPP}class{$ENDIF} function GetFlags:TkbmMWServiceFlags; override;
  end;
 
implementation
 
uses kbmMWExceptions, unt_main, unt_dm;
 
{$R *.dfm}
 
// Service definitions.
//---------------------
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetPrefServiceName:string;
begin
     Result:='demoservice';
end;
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetVersion:string;
begin
     Result:='1.0';
end;
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetFlags:TkbmMWServiceFlags;
begin
     Result:=[mwsfListed];
end;
 
function TkbmMWSimpleService1.ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
   AFunc:string;
begin
     AFunc:=UpperCase(Func);
     if AFunc='UPDATE' then // 关联到PerformUpdate函数
        Result:=PerformUpdate(ClientIdent,Args)
     else
     if AFunc='SELECT' then // 关联到PerformSelect 函数
        Result:=PerformSelect(ClientIdent,Args)
     else Result:=inherited ProcessRequest(Func,ClientIdent,Args);
end;
 
function TkbmMWSimpleService1.PerformUpdate(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
  param: string;
  aQuery: TADOQuery;
  aconn: TkbmMWADOXConnection;
begin
  Result := 0;
  param :=args[0]; //取出参数
  aQuery := TADOQuery.Create(nil);
  //从数据库连接池中取出可用链接
  aconn := TkbmMWADOXConnection(DataModule1.kbmMWADOXConnectionPool1.GetBestConnection(True,0,nil,10000));
  if aconn = nil then
  begin
    kbmMWRaiseServerException('无可用的数据库连接');
    Exit;
  end;
  aQuery.Connection := aconn.Database;
  aQuery.SQL.Text := 'update devinfo set dev_name=:param where id < 10';
  aQuery.Parameters.ParamByName('param').Value := param; //传入参数
  try
    try
      aQuery.ExecSQL;
      Result := aQuery.RowsAffected;//返回影响条数
    except
      Result := -1; //错误时返回-1
    end;
  finally
    aconn.UnlockConnection;
    aQuery.Free;
  end;
end;
 
function TkbmMWSimpleService1.PerformSelect(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
  param: string;
  aQuery: TADOQuery;
  aconn: TkbmMWADOXConnection;
  memTable: TkbmMemTable; //内存表类
  aStreamFormat: TkbmBinaryStreamFormat; //流格式类
begin
  Result := 0;
  param :=args[0]; //取出参数
  aQuery := TADOQuery.Create(nil);
  //从数据库连接池中取出可用链接
  aconn := TkbmMWADOXConnection(DataModule1.kbmMWADOXConnectionPool1.GetBestConnection(True,0,nil,10000));
  if aconn = nil then
  begin
    kbmMWRaiseServerException('无可用的数据库连接');
    Exit;
  end;
  aQuery.Connection := aconn.Database;
  aQuery.SQL.Text := 'select * from devinfo where dev_name=:param';
  aQuery.Parameters.ParamByName('param').Value := param; //传入参数
  //初始化内存表
  memTable := TkbmMemTable.Create(nil);
  //初始化流格式
  aStreamFormat := TkbmBinaryStreamFormat.Create(nil);
  //内存表设置
  memTable.DefaultFormat := aStreamFormat;
  memTable.IndexFieldNames := '';
  memTable.SortFields := '';
  memTable.MasterSource := nil;
  try
    try
      aQuery.Open;
      Result := aQuery.RecordCount;//返回记录条数
      //导入结果到流
      memTable.LoadFromDataSet(aQuery,[mtcpoStructure,mtcpoProperties]);
      //格式化流
      memTable.SaveToStreamViaFormat(ResultStream,aStreamFormat);
    except
      Result := -1; //错误时返回-1
    end;
  finally
    aconn.UnlockConnection;
    aQuery.Free;
    memTable.Free;
    aStreamFormat.Free;
  end;
end;
 
end.
  • 客户端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
unit unt_main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,kbmMemTable, kbmMemBinaryStreamFormat,
  kbmMWCustomTransport, kbmMWClient, kbmMWTCPIPIndyClientTransport,
  kbmMWClientDataset, kbmMWCustomConnectionPool, Grids, DBGrids, DB, StdCtrls;
 
type
  Tmainform = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    kbmMWSimpleClient1: TkbmMWSimpleClient;
    kbmMWTCPIPIndyClientTransport1: TkbmMWTCPIPIndyClientTransport;
    Edit2: TEdit;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  mainform: Tmainform;
  aStreamFormat: TkbmBinaryStreamFormat;
  kbmMemTable: TkbmMemTable;
 
implementation
 
{$R *.dfm}
 
procedure Tmainform.Button1Click(Sender: TObject);
var
  args: array[0..1] of Variant;
  res: Integer;
begin
  Edit2.Text := '';
  args[0]:= Edit1.Text; //参数
  res := kbmMWSimpleClient1.Request('demoservice','','SELECT',args); //发起请求
  kbmMemTable.EmptyTable; //清空内存表
  kbmMemTable.LoadFromStreamViaFormat(kbmMWSimpleClient1.ResultStream,aStreamFormat); //导入结果流
  Edit2.Text := IntToStr(res);
end;
 
procedure Tmainform.Button2Click(Sender: TObject);
var
  args: array[0..1] of Variant;
  res: Integer;
begin
  Edit2.Text := '';
  args[0]:= Edit1.Text; //参数
  res := kbmMWSimpleClient1.Request('demoservice','','UPDATE',args); //发起请求
  Edit2.Text := IntToStr(res); //返回值
end;
 
procedure Tmainform.FormCreate(Sender: TObject);
begin
  aStreamFormat := TkbmBinaryStreamFormat.Create(nil);
  kbmMemTable := TkbmMemTable.Create(nil);
  kbmMemTable.DefaultFormat := aStreamFormat;
  DataSource1.DataSet := kbmMemTable; //设置dataset为内存表
end;
 
end.

二、利用ClientDataSet:

  • 服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
unit unt_service_func;
// =========================================================================
// kbmMW - An advanced and extendable middleware framework.
// by Components4Developers (http://www.components4developers.com)
//
// Service generated by kbmMW service wizard.
//
// INSTRUCTIONS FOR REGISTRATION/USAGE
// -----------------------------------
// Please update the uses clause of the datamodule/form the TkbmMWServer is placed on by adding
// YourServiceUnitName to it. Eg.
//
// uses ...,kbmMWServer,YourServiceUnitName;
//
// Somewhere in your application, make sure to register the serviceclass to the TkbmMWServer instance. Eg.
//
// var
// sd:TkbmMWCustomServiceDefinition;
// ..
// sd:=kbmMWServer1.RegisterService(yourserviceclassname,false);
//
// Set the last parameter to true if this is the default service.
//
 
{$I kbmMW.inc}
 
interface
 
uses
SysUtils,
{$ifdef LEVEL6}
Variants,
{$else}
Forms,
{$endif}
Classes,
kbmMWSecurity,
kbmMWServer,
kbmMWServiceUtils,
kbmMWGlobal,
kbmMWADOX,DB, ADODB,MidasLib,DBClient,Provider;
 
type
TkbmMWSimpleService1 = class(TkbmMWSimpleService)
private
{ Private declarations }
protected
{ Protected declarations }
//新增以下函数
function ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; override;
function PerformUpdate(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; virtual;
function PerformSelect(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; virtual;
public
{ Public declarations }
{$IFNDEF CPP}class{$ENDIF} function GetPrefServiceName:string; override;
{$IFNDEF CPP}class{$ENDIF} function GetVersion:string; override;
{$IFNDEF CPP}class{$ENDIF} function GetFlags:TkbmMWServiceFlags; override;
end;
 
implementation
 
uses kbmMWExceptions, unt_main, unt_dm;
 
{$R *.dfm}
 
// Service definitions.
//---------------------
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetPrefServiceName:string;
begin
Result:='demoservice';
end;
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetVersion:string;
begin
Result:='1.0';
end;
 
{$IFNDEF CPP}class{$ENDIF} function TkbmMWSimpleService1.GetFlags:TkbmMWServiceFlags;
begin
Result:=[mwsfListed];
end;
 
function TkbmMWSimpleService1.ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
AFunc:string;
begin
AFunc:=UpperCase(Func);
if AFunc='UPDATE' then // 关联到PerformUpdate函数
Result:=PerformUpdate(ClientIdent,Args)
else
if AFunc='SELECT' then // 关联到PerformSelect 函数
Result:=PerformSelect(ClientIdent,Args)
else Result:=inherited ProcessRequest(Func,ClientIdent,Args);
end;
 
function TkbmMWSimpleService1.PerformUpdate(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
param: string;
aQuery: TADOQuery;
aconn: TkbmMWADOXConnection;
begin
Result := 0;
param :=args[0]; //取出参数
aQuery := TADOQuery.Create(nil);
//从数据库连接池中取出可用链接
aconn := TkbmMWADOXConnection(DataModule1.kbmMWADOXConnectionPool1.GetBestConnection(True,0,nil,10000));
if aconn = nil then
begin
kbmMWRaiseServerException('无可用的数据库连接');
Exit;
end;
aQuery.Connection := aconn.Database;
aQuery.SQL.Text := 'update devinfo set dev_name=:param where id < 10';
aQuery.Parameters.ParamByName('param').Value := param; //传入参数
try
try
aQuery.ExecSQL;
Result := aQuery.RowsAffected;//返回影响条数
except
Result := -1; //错误时返回-1
end;
finally
aconn.UnlockConnection;
aQuery.Free;
end;
end;
 
function TkbmMWSimpleService1.PerformSelect(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
param: string;
aQuery: TADOQuery;
aconn: TkbmMWADOXConnection;
CDS: TClientDataSet;
DSP: TDataSetProvider;
MS: TMemoryStream;
begin
Result := 0;
param :=args[0]; //取出参数
aQuery := TADOQuery.Create(nil);
//从数据库连接池中取出可用链接
aconn := TkbmMWADOXConnection(DataModule1.kbmMWADOXConnectionPool1.GetBestConnection(True,0,nil,10000));
if aconn = nil then
begin
kbmMWRaiseServerException('无可用的数据库连接');
Exit;
end;
aQuery.Connection := aconn.Database;
aQuery.SQL.Text := 'select * from devinfo where dev_name=:param';
aQuery.Parameters.ParamByName('param').Value := param; //传入参数
CDS := TClientDataSet.Create(nil);
DSP := TDataSetProvider.Create(nil);
MS := TMemoryStream.Create;
try
try
aQuery.Open;
Result := aQuery.RecordCount;//返回记录条数
DSP.DataSet := aQuery; //关联DataSet
CDS.Data := DSP.Data; //传递给ClientDataSet
CDS.SaveToStream(MS,dfBinary); //另存为内存流
MS.Position := 0;
ResultStream.LoadFromStream(MS); //导入到结果流
except
Result := -1; //错误时返回-1
end;
finally
aconn.UnlockConnection;
aQuery.Free;
CDS.Free;
DSP.Free;
MS.Free;
end;
end;
 
end.
  • 客户端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
unit unt_main;
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,kbmMWCustomTransport, kbmMWClient, kbmMWTCPIPIndyClientTransport,
kbmMWClientDataset, kbmMWCustomConnectionPool, Grids, DBGrids, DB, StdCtrls,
MidasLib,DBClient;
 
type
Tmainform = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
kbmMWSimpleClient1: TkbmMWSimpleClient;
kbmMWTCPIPIndyClientTransport1: TkbmMWTCPIPIndyClientTransport;
Edit2: TEdit;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
 
var
mainform: Tmainform;
CDS: TClientDataSet;
 
implementation
 
{$R *.dfm}
 
procedure Tmainform.Button1Click(Sender: TObject);
var
args: array[0..1] of Variant;
res: Integer;
begin
Edit2.Text := '';
args[0]:= Edit1.Text; //参数
res := kbmMWSimpleClient1.Request('demoservice','','SELECT',args); //发起请求
CDS.LoadFromStream(kbmMWSimpleClient1.ResultStream);//从结果流中导入
Edit2.Text := IntToStr(res);
end;
 
procedure Tmainform.Button2Click(Sender: TObject);
var
args: array[0..1] of Variant;
res: Integer;
begin
Edit2.Text := '';
args[0]:= Edit1.Text; //参数
res := kbmMWSimpleClient1.Request('demoservice','','UPDATE',args); //发起请求
Edit2.Text := IntToStr(res);
end;
 
procedure Tmainform.FormCreate(Sender: TObject);
begin
CDS := TClientDataSet.Create(nil);
DataSource1.DataSet := CDS; //设置dataset
end;
 
procedure Tmainform.FormDestroy(Sender: TObject);
begin
CDS.Free;
end;
 
end.

转载请注明:梧桐树下 » KbmMW两种查询结果集通讯方式

http://www.pfeng.org/archives/671

KbmMW两种查询结果集通讯方式的更多相关文章

  1. easyui datagride 两种查询方式

    easyui datagride 两种查询方式function doReseach() { //$('#tt').datagrid('load', { // FixedCompany: $('.c_s ...

  2. LINQ to Objects系列(2)两种查询语法介绍

    LINQ为我们提供了两种查询语法,分别是查询表达式和查询方法语法.这篇文章分为以下几个方面进行总结. 1,一个包含两种查询语法的简单示例 2,查询表达式的结构 3,查询方法相关的运算符 一个包含两种查 ...

  3. reportConfig.xml两种数据源连接的配置方式

     在reportConfig.xml配置文件中,我们提供了两种数据源连接的配置方式,分别如下: 1.jndi数据源配置(即:在dataSource中配置) 此配置适用于在j2ee的服务器中配置了j ...

  4. ZOJ-1610 线段树+两种查询方法(弥补我线段树区间填充的短板)

    ZOJ-1610 线段树+两种查询方法(弥补我线段树区间填充的短板) 题意 题意:给一个n,代表n次操作,接下来每次操作表示把[l,r]区间的线段涂成k的颜色其中,l,r,k的范围都是0到8000 这 ...

  5. 流式思想概述和两种获取Stream流的方式

    流式思想概述 整体来看,流式思想类似于工厂车间的生产流水线 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个模型步骤方案,然后再按照方法去执行他 这张图中展示 ...

  6. 关于使用lazytag的线段树两种查询方式的比较研究

    说到线段树,想来大家并不陌生——最基本的思路就是将其规划成块,然后只要每次修改时维护一下即可. 但是尤其是涉及到区间修改时,lazytag的使用往往能够对于程序的质量起到决定性作用(Ex:一般JSOI ...

  7. Android APP 两种用程序拨号的方式

    想在APP中添加一个拨号功能该怎样做呢?Android提供了两种方式,一种是ACTION_CALL方式直接拨打,另一种是ACTION_DIAL方式打开系统的拨号界面. 下面我们来做个小例子 首先需要在 ...

  8. js两种定义函数、继承方式及区别

    一:js两种定义函数的方式及区别 1:函数声明: function sayA() { alert("i am A"); } 2:函数表达式: var sayB = function ...

  9. WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式

    1.本地化支持 (1)重写控件默认的依赖属性LanguageProperty FrameworkElement.LanguageProperty.OverrideMetadata( typeof(Fr ...

随机推荐

  1. uber奖励和账单详解

    为了让各位车主轻松理解奖励政策和账单明细的核算方法,我们特意制作#奖励详解#的专题文章,保证您五分钟内掌握看懂账单的全部要领和诀窍. 第一部分:收入说明 看到收入说明的账单是不是有些晕呢,来来,我们一 ...

  2. Uber司机一周体验记:成单率仅57%

    虽然注册过程不顺利,但耗时一下午终究还是当上人民优步司机了.而且一周下来也完成了十几单,个中滋味恐怕只有载着陌生的乘客开上路才能体会. 第一单 一位赶去面试的年轻人,刚来北京两年,因为路线不熟坐错了公 ...

  3. solaris 操作系统配置联网

    1. 设置主机名: etc/hostname.vmxnet0 hannick 2.设置主机名和ip地址的映射: etc/hosts 127.0.0.1 localhost 192.108.1.123 ...

  4. linux网络编程涉及的函数

    常用的网络命令: netstat 命令netstat是用来显示网络的连接,路由表和接口统计等网络的信息. netstat有许多的选项我们常用的选项是-an用来显示详细的网络状态.至于其它选项我们使用帮 ...

  5. C#中数组、ArrayList和List三者的区别(转)

    好东西,总结的很到位,收藏了! 源地址:http://blog.csdn.net/zhang_xinxiu/article/details/8657431

  6. ssh环境搭建并实现登录功能

    参照了这篇博客,但是里面有些地方进行了更改 http://wenku.baidu.com/link?url=edeegTquV2eR3CJ5-zvNcJbyuq11Afp-lD2Fz2jfmuHhV1 ...

  7. STL: generate ,geterate_n

    在随机生成一定范围不重复数时用到random_shuffle函数,之前填充数组都是用for循环, 想到之前python中的range生成序列,于是在C++中找到对应的generate用来生成所需数组. ...

  8. (转)经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  9. Spring学习之注入方式

    我们知道,Spring对象属性的注入方式有两种:设值注入和构造注入. 假设有个类为People,该对象包含三个属性,name和school还有age,这些属性都有各自的setter和getter方法, ...

  10. cocos2d-x spine 加载粒子特效

    spine骨骼加载粒子效果 将粒子效果加到骨骼上,update位置和角度.h#ifndef __HOMESCENE_H__#define __HOMESCENE_H__#include "c ...