那种往应用服务器中拖放一堆TDataSet, TDaTaSetProvider控件的做法,非常的笨拙。可以通过使用对象池来改进之。
数据集对象池
unit ServerMethodsUnit1;
interface
uses SysUtils, Classes, DSServer, DB, Generics.Collections, DSService, Provider, ADODB;
type TServerMethods1 = class(TDSServerModule) procedure DSServerModuleCreate(Sender: TObject); private { Private declarations } ListofQuery : TDictionary<Integer,Tadoquery>; ListofProvider : TDictionary<Integer,Tdatasetprovider>; function _GetQuery(asql: string; exeNo: Integer) : Tadoquery; function _GetPrv(sql: string; exeNo: Integer) : Tdatasetprovider; public { Public declarations } function GetProviderName(sql: string; exeNo: Integer): string; end;
implementation
{$R *.dfm}
uses StrUtils, DSServerContainer, uConst;
procedure TServerMethods1.DSServerModuleCreate(Sender: TObject);begin Listofquery := TDictionary<Integer, Tadoquery>.Create; Listofprovider := TDictionary<Integer, Tdatasetprovider>.Create;end;
function TServerMethods1._GetPrv(sql: string; exeNo: Integer): Tdatasetprovider;var dbprv : Tdatasetprovider;begin if ListofProvider.ContainsKey(exeNo) then Result := ListofProvider[exeNo] else begin if ListofProvider.Count <= g_MaxPoolSize then begin dbprv := TDataSetProvider.Create(Self); dbprv.Name := 'dsp'+ IntToStr(exeNo); dbprv.DataSet := _GetQuery(sql, exeNo); ListofProvider.Add(exeNo, dbprv); Result := dbprv; end; end;end;
function TServerMethods1._GetQuery(asql: string; exeNo: Integer): Tadoquery;var qry : TADOQuery;begin if Listofquery.ContainsKey(exeNo) then Result := ListofQuery[exeNo] else begin if ListofQuery.Count <= g_MaxPoolSize then begin qry := TADOQuery.Create(Self); with qry do begin Connection := ServerContainer1.GetConnection; Name := 'qry'+ IntToStr(exeNo); close; sql.Clear; sql.Text := asql; open; end; ListofQuery.Add(exeNo, qry); Result := qry; end; end;end;
function TServerMethods1.GetProviderName(sql: string; exeNo: Integer): string;begin Result := _GetPrv(sql, exeNo).Name;end;
end.
连接池
unit DSServerContainer;
interface
uses SysUtils, Classes, DSTCPServerTransport, DSServer, DSCommonServer, DSAuth, DB, ADODB, Generics.Collections, DSService, DBXDataSnap, DBXCommon, DSHTTPLayer, DBXinterbase, forms;
type TServerContainer1 = class(TDataModule) DSServer1: TDSServer; DSTCPServerTransport1: TDSTCPServerTransport; DSServerClass1: TDSServerClass; procedure DSServerClass1GetClass(DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass); procedure DataModuleCreate(Sender: TObject); procedure DSServer1Disconnect(DSConnectEventObject: TDSConnectEventObject); private { Private declarations } ListofConnection : TDictionary<Integer,TadoConnection>; public function GetConnection : TadoConnection; end;
var ServerContainer1: TServerContainer1;
implementation
uses Windows, ServerMethodsUnit1,uConst;
{$R *.dfm}
procedure TServerContainer1.DataModuleCreate(Sender: TObject);begin ListofConnection := TDictionary<Integer, TadoConnection>.Create;end;
procedure TServerContainer1.DSServer1Disconnect( DSConnectEventObject: TDSConnectEventObject);begin if GetConnection <> nil then GetConnection.Close;end;
procedure TServerContainer1.DSServerClass1GetClass( DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);begin PersistentClass := ServerMethodsUnit1.TServerMethods1;end;
function TServerContainer1.GetConnection: TadoConnection;var dbconn : TadoConnection;begin if ListofConnection.ContainsKey(TDSSessionManager.GetThreadSession.Id) then Result := ListofConnection[TDSSessionManager.GetThreadSession.Id] else begin if ListofConnection.Count <= g_MaxPoolSize then begin dbconn := TadoConnection.Create(Self); dbconn.Name := 'con'+ IntToStr(TDSSessionManager.GetThreadSession.Id); dbconn.LoginPrompt := false; dbconn.ConnectionString := 'FILE NAME=' + extractfilepath(application.ExeName) + 'connect.udl'; ListofConnection.Add(TDSSessionManager.GetThreadSession.Id, dbconn); Result := dbconn; end; end;end;
end.