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