三层中数据库服务器的连接看情况而定,一般情况下是保持连接,用一个adoconnection,里面不是有一项叫keepconnection来着
解决方案 »
- delphi里安装的组件为什么关掉delphi重新打开就不见了
- fastreport报表问题
- 用过fastreport的大侠请进来看下......急!!谢谢!!
- IW控件:IWDBLookupComboBox 的一个使用方法或属性 设置问题
- 急急急:关于keydown事件的问题?
- 一个关于字符串的小问题请大侠帮忙。
- 如何才能用程序更改文件名称呀
- 怎么修改dbgrid中的某几条的记录值?
- 高分求救!!!!!!!!!!!!
- 编写局域网网络同步教学,在教师机上的操作在学生机上同步显示这样的软件都需要学习什么知识(请大家具体讲讲)什么样的编程语言最好
- 请问!!!:delphi中 image控件的无级放大源码?
- 高分求助,为什么Windows窗口上的... UP有分。
“应该尽量重复使用数据库连接,因为数据库连接是个费时间的事情,这方面的问题非常复杂,你需要多看看李维的书。” 李维的书说得的确是很理想,但有谁真正用他所阐述的方法开发过系统,如果有,效果是不是好呢?再好的思想观点都得经过实践检验是否可行,如果只是他书上那些简单例子来做论据未免站不住脚,何况上面的例子还有很多没有实现,至少我是如此!
一家之言,尽供参考,请大家多发言讨论!
说实话,我也看过李维的两本书,不过感觉实际上很多照书上做,走不下去。
其实,很多要靠自己去试。
Function AS_GetProviderNames: OleVariant;
Safecall;
Function AS_ApplyUpdates(Const ProviderName :WideString; Delta :OleVariant;
MaxErrors :Integer; Out ErrorCount :Integer; Var OwnerData :OleVariant)
:OleVariant; Safecall;
Function AS_GetRecords(Const ProviderName :WideString; Count :Integer;
Out RecsOut :Integer; Options :Integer; Const CommandText :WideString;
Var Params, OwnerData :OleVariant)
:OleVariant; Safecall;
Function AS_DataRequest(Const ProviderName :WideString; Data :OleVariant)
:OleVariant; Safecall;
Function AS_GetParams(Const ProviderName :WideString;
Var OwnerData :OleVariant)
:OleVariant; Safecall;
Function AS_RowRequest(Const ProviderName :WideString; Row :OleVariant;
RequestType :Integer; Var OwnerData :OleVariant)
:OleVariant; Safecall;
Procedure AS_Execute(Const ProviderName :WideString; Const CommandText
:WideString; Var Params, OwnerData :OleVariant);
Safecall;Function TXXXRemoteDataModule.AS_ApplyUpdates(Const ProviderName: WideString;
Delta: OleVariant; MaxErrors: Integer; Out ErrorCount: Integer;
Var OwnerData: OleVariant)
:OleVariant;
Var
Provider :TCustomProvider;
Begin
Lock;
Try
Provider := Providers[ProviderName];
If Provider.Tag = 0 Then Result := Provider.ApplyUpdates(Delta,
MaxErrors, ErrorCount, OwnerData)
Else Begin
Result := TModuleConnection(Provider.Tag).AS_ApplyUpdates
(Provider.Name, Delta, MaxErrors, ErrorCount, OwnerData);
End;
Finally
UnLock;
End;
End;我利用 CustomProvider (TRemoteDataModule 中定义)中的 Tag, 来存放 TModuleConnection 地址, TModuleConnection 是我写的一个控件, 可以认为是一个 TList 用于存放先分配好的那些 Connection
TPooleredConnection = Class;
TModuleConnection = Class(TComponent)
Private
FConnections :TList;
FCacheCount :Integer;
FCriticalSection :TCriticalSection;
FServerName :AnsiString;
FServerGUID :TGUID; Procedure SetServerName(Value :AnsiString);
Procedure SetServerGUID(Value :AnsiString);
Function GetServerGUID( ) :AnsiString;
Procedure SetCacheCount( Value :Integer );
Function GetConnectionCount :Integer;
Protected
Procedure Loaded; Override;
Function GetLock( Index :Integer ) :Boolean;
Function CreateNewConnection( ) :TPooleredConnection;
Procedure RemoveConnection( Connection :TPooleredConnection );
Public
Constructor Create( AOwner :TComponent ); Override;
Destructor Free( );
Function GetConnection( ) :TPooleredConnection;
Procedure ReleaseConnection(Connection :TPooleredConnection);
{ IAppServer methods }
Function AS_GetProviderNames: OleVariant;
Function AS_ApplyUpdates(Const ProviderName :WideString; Delta :OleVariant;
MaxErrors :Integer; Out ErrorCount :Integer; Var OwnerData :OleVariant)
:OleVariant;
Function AS_GetRecords(Const ProviderName :WideString; Count :Integer;
Out RecsOut :Integer; Options :Integer; Const CommandText :WideString;
Var Params, OwnerData :OleVariant)
:OleVariant;
Function AS_DataRequest(Const ProviderName :WideString; Data :OleVariant)
:OleVariant;
Function AS_GetParams( Const ProviderName :WideString;
Var OwnerData :OleVariant)
:OleVariant;
Function AS_RowRequest( Const ProviderName :WideString; Row :OleVariant;
RequestType :Integer; Var OwnerData :OleVariant)
:OleVariant;
Procedure AS_Execute( Const ProviderName :WideString; Const CommandText
:WideString; Var Params, OwnerData :OleVariant);
Published
Property ServerName :AnsiString Read FServerName Write SetServerName;
Property ServerGUID :AnsiString Read GetServerGUID Write SetServerGUID;
Property CacheCount :Integer Read FCacheCount Write SetCacheCount Default 10;
Property ConnectionCount :Integer Read GetConnectionCount;
End;
//---------------------------------------------------------------------------
// { DONE -oBin. :TModuleConnection implementation
//---------------------------------------------------------------------------
Constructor TModuleConnection.Create( AOwner :TComponent );
Begin
Inherited Create( AOwner ); FCacheCount := 10;
FConnections := TList.Create( );
FCriticalSection := TCriticalSection.Create( );
End;
//---------------------------------------------------------------------------
Destructor TModuleConnection.Free( );
Var
i :Integer;
Begin
For i := 0 To FConnections.Count Do
TPooleredConnection( FConnections[i] ).Free( );
FConnections.Free( );
FCriticalSection.Free( );
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.SetServerName( Value :AnsiString );
Begin
If Value <> FServerName Then
Begin
If Not ( csLoading In ComponentState ) Then
Begin
If CLSIDFromProgID( PWideChar( WideString( Value ) ), FServerGUID )
<> 0 Then
Begin
FillChar( FServerGUID, SizeOf( FServerGUID ), 0 );
End;
End;
FServerName := Value;
End;
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.SetServerGUID( Value :AnsiString );
Var
ServerName: PWideChar;
Begin
If Value = '' Then FillChar( FServerGUID, SizeOf( FServerGUID ), 0 )
Else Begin
FServerGUID := StringToGUID( Value );
If ProgIDFromCLSID( FServerGUID, ServerName ) = 0 Then
Begin
FServerName := ServerName;
CoTaskMemFree(ServerName);
End;
End;
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.SetCacheCount( Value :Integer );
Begin
FCacheCount := Value;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.GetConnectionCount :Integer;
Begin
Result := FConnections.Count;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.GetServerGUID( ) :AnsiString;
Begin
If ( FServerGUID.D1 <> 0 ) Or
( FServerGUID.D2 <> 0 ) Or
( FServerGUID.D3 <> 0 ) Then
Begin
Result := GUIDToString( FServerGUID )
End
Else Result := '';
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.Loaded;
Begin
Inherited Loaded; If Not (csDesigning In ComponentState) Then
Begin
End;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.GetLock( Index :Integer ) :Boolean;
Begin
FCriticalSection.Enter( );
Try
Result := Not TPooleredConnection( FConnections[Index] ).InUse;
If Result Then
TPooleredConnection( FConnections[Index] ).InUse := True;
Finally
FCriticalSection.Leave( );
End;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.GetConnection( ) :TPooleredConnection;
Var
i :Integer;
Begin
Result := Nil;
For i := 0 To FConnections.Count-1 Do
Begin
If GetLock( i ) Then
Begin
Result := TPooleredConnection( FConnections[i] );
Exit;
End;
End;
If Result = Nil Then Result := CreateNewConnection;
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.ReleaseConnection( Connection :TPooleredConnection );
Begin
FCriticalSection.Enter;
Try
Connection.InUse := False;
If FConnections.Count > FCacheCount Then
RemoveConnection( Connection );
Finally
FCriticalSection.Leave;
End;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.CreateNewConnection( ) :TPooleredConnection;
Begin
FCriticalSection.Enter( );
Try
Result := TPooleredConnection.Create( );
Result.Connection := CreateComObject( FServerGUID ) As IAppServer;
FConnections.Add( Result );
Finally
FCriticalSection.Leave( );
End;
End;
//---------------------------------------------------------------------------
Procedure TModuleConnection.RemoveConnection( Connection :TPooleredConnection );
Var
Index :Integer;
Begin
Index := FConnections.IndexOf( Connection );
If Index <> -1 Then FConnections.Delete( Index );
Connection.Free;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.AS_GetProviderNames: OleVariant;
Var
Connection :TPooleredConnection;
Begin
Connection := GetConnection( );
Try
Result := Connection.AppServer.AS_GetProviderNames;
Finally
ReleaseConnection( Connection );
End;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.AS_ApplyUpdates( Const ProviderName :WideString;
Delta :OleVariant; MaxErrors :Integer; Out ErrorCount :Integer;
Var OwnerData :OleVariant ) :OleVariant;
Var
Connection :TPooleredConnection;
Begin
Connection := GetConnection( );
Try
Result := Connection.AppServer.AS_ApplyUpdates( ProviderName,
Delta, MaxErrors, ErrorCount, OwnerData );
Finally
ReleaseConnection( Connection );
End;
End;
//---------------------------------------------------------------------------
Function TModuleConnection.AS_GetRecords( Const ProviderName :WideString;
Count :Integer; Out RecsOut :Integer; Options :Integer;
Const CommandText:WideString; Var Params, OwnerData :OleVariant) :OleVariant;
Var
Connection :TPooleredConnection;
Begin
Connection := GetConnection( );
Try
Result := Connection.AppServer.AS_GetRecords( ProviderName,
Count, RecsOut, Options, CommandText, Params, OwnerData );
Finally
ReleaseConnection( Connection );
End;
End;