我的想法是,把ADOConnection放在一个单独的DBConn.dll, 其它的操作比如用户登录、增加记录等操作封装 在各自的dll中,这些dll共享DBConn.dll的连接。示例代码如下:(我想问的问题是:这样做的话,每次调用DBConn.dll, 都要重建连接,并没起到共享连接的作用,该怎么优化呢?或者 有没有更好的其它方式?)library DBConn;uses SysUtils, forms, Classes, DB, ADODB, windows;var ADOConn:TADOConnection;procedure MyDllProc(Reason:integer); begin if Reason=DLL_PROCESS_DETACH then ADOConn.Free; end;function GetConn: TADOConnection; begin result:=ADOConn; end;{$R *.res}exports GetConn;begin ADOConn:=TADOConnection.Create(Application); ADOConn.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=ecsms'; ADOConn.KeepConnection:=true; DLLProc:=@MyDllProc; end.============= library Login; //CheckUser函数用来验证用户 uses ShareMem, SysUtils, Classes, DB, ADODB, windows, forms, dialogs;type TGetConn=function:TADOConnection; var adoq:TADOQuery; DLLInstance:THandle; GetConn:TGetConn;function CheckUser(account,password:string):boolean; begin result:=true; DLLInstance:=loadlibrary('DBConn.dll'); if DLLInstance=0 then begin result:=false; Messagedlg('Unabel to load DBConn.dll',mtError,[mbOK],0); exit; end; @GetConn:=GetProcAddress(DLLInstance,'GetConn'); if @GetConn=nil then begin result:=false; Messagedlg('Unable to locate function GetConn in DBConn.dll',mtError,[mbok],0); FreeLibrary(DLLInstance); exit; end; adoq.Connection:=GetConn; with adoq do begin if active then close; sql.Clear; sql.Text:='select * from ecsms_user where user_account='''+account+'''' +' and password='''+password+''''; try open; if RecordCount=0 then result:=false; finally close; end; end; end;exports CheckUser;{$R *.res}begin adoq:=TADOQuery.Create(Application); end.
unit Main; {$DEFINE ADOCONNECT}interfaceUses DB, ADODB, Classes, ActiveX;{$I ADO.Inc}Function InitADO( ConnectString : WideString ) : TADOConnect; Stdcall;implementation{ TADOConnect }Constructor TADOConnect.Create( ConnectString : WideString ); begin Inherited Create; CoInitialize( Nil ); FConnectString := ConnectString; FADO := TADOConnection.Create( Nil ); FADO.ConnectionString := FConnectString; FADO.LoginPrompt := False; end;Destructor TADOConnect.Destroy; Begin FADO.Free; CoUninitialize; Inherited Destroy; End;Function TADOConnect.Open : Boolean; Begin Try FADO.Open; Result := True; Except Result := False; End; End;Function TADOConnect.Close : Boolean; Begin Try FADO.Close; Result := True; Except Result := False; End; End;Function TADOConnect.GetConnection : TADOConnection; Begin Result := FADO; End;Procedure TADOConnect.GetTableNames( Var List : TStringList; IncludeSysTable : Boolean ); Begin If FADO.Connected Then FADO.GetTableNames( List, IncludeSysTable ); End;Procedure TADOConnect.GetFieldNames( Const TableName : String; Var List : TStringList ); Begin If FADO.Connected Then FADO.GetFieldNames( TableName, List ); End;Procedure TADOConnect.GetProcedureNames( Var List : TStringList ); Begin If FADO.Connected Then FADO.GetProcedureNames( List ); End;Function TADOConnect.GetConnectState : Boolean; Begin Result := FADO.Connected; End;Function InitADO( ConnectString : WideString ) : TADOConnect; Begin Result := TADOConnect.Create( ConnectString ); End;end.Ado.Inc Type TADOConnect = Class( TObject ) {$IFDEF ADOCONNECT} Private FConnectString : WideString; FADO : TADOConnection; {$ENDIF} Public {$IFDEF ADOCONNECT} Constructor Create( ConnectString : WideString ); Destructor Destroy; Override; {$ENDIF} Function Open : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Function Close : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Function GetConnection : TADOConnection; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Function GetConnectState : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Procedure GetTableNames( Var List : TStringList; IncludeSysTable : Boolean = False ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Procedure GetFieldNames( Const TableName : String; Var List : TStringList ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} Procedure GetProcedureNames( Var List : TStringList ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF} End;ADo.Dpr library ADO;{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }uses SysUtils, Classes, Main in 'Main.pas';{$R *.res}Exports InitADO; End.
先说应用服务器的连接: 知道APP 的Server不就可以了吗
再说数据库的连接: 知道连接字符串不也可以了吗
那么, 在连接APP 时去连接DB, 不就OK了
连接APP 时要注意创建一个Connection,最后把它给Free 掉, 连接DB 的参数最好放在文件中,不过口令可以做些特殊处理,最简单的就是加个密什么的.不知道上面的是不是就是楼主想要的, 理解错了莫怪.
其它的操作比如用户登录、增加记录等操作封装
在各自的dll中,这些dll共享DBConn.dll的连接。示例代码如下:(我想问的问题是:这样做的话,每次调用DBConn.dll,
都要重建连接,并没起到共享连接的作用,该怎么优化呢?或者
有没有更好的其它方式?)library DBConn;uses
SysUtils,
forms,
Classes,
DB,
ADODB,
windows;var
ADOConn:TADOConnection;procedure MyDllProc(Reason:integer);
begin
if Reason=DLL_PROCESS_DETACH then
ADOConn.Free;
end;function GetConn: TADOConnection;
begin
result:=ADOConn;
end;{$R *.res}exports
GetConn;begin
ADOConn:=TADOConnection.Create(Application);
ADOConn.ConnectionString:='Provider=MSDASQL.1;Persist Security Info=False;Data Source=ecsms';
ADOConn.KeepConnection:=true;
DLLProc:=@MyDllProc;
end.=============
library Login; //CheckUser函数用来验证用户
uses
ShareMem,
SysUtils,
Classes,
DB,
ADODB,
windows,
forms,
dialogs;type
TGetConn=function:TADOConnection;
var
adoq:TADOQuery;
DLLInstance:THandle;
GetConn:TGetConn;function CheckUser(account,password:string):boolean;
begin
result:=true;
DLLInstance:=loadlibrary('DBConn.dll');
if DLLInstance=0 then
begin
result:=false;
Messagedlg('Unabel to load DBConn.dll',mtError,[mbOK],0);
exit;
end;
@GetConn:=GetProcAddress(DLLInstance,'GetConn');
if @GetConn=nil then
begin
result:=false;
Messagedlg('Unable to locate function GetConn in DBConn.dll',mtError,[mbok],0);
FreeLibrary(DLLInstance);
exit;
end;
adoq.Connection:=GetConn;
with adoq do
begin
if active then close;
sql.Clear;
sql.Text:='select * from ecsms_user where user_account='''+account+''''
+' and password='''+password+'''';
try
open;
if RecordCount=0 then result:=false;
finally
close;
end;
end;
end;exports
CheckUser;{$R *.res}begin
adoq:=TADOQuery.Create(Application);
end.
其实你这样的做DLL与主程序仍是运行在同一进程中,那还不如把连接动作做在主程序中,DLL通过查找主程序的TADOConnection,从而达到共享的目的。具体的做法为:在主程序的某个单元中:ADOConn := TADOConnection.Create(Application) ;
ADOConn.Name := 'g_ADOConn' ;
ADOConn.ConnectString :='你取来的连接串'
ADOConn.Open ;在数据操作DLL中:AConn := Application.FindComponent('g_ADOConn') as TADOConnection ;qry.Connection := AConn ;
多谢!
我觉得把数据库连接和数据存取方在dll中意义不大,还不如放在
主程序中的数据模块中,你觉得呢?
{$DEFINE ADOCONNECT}interfaceUses DB, ADODB, Classes, ActiveX;{$I ADO.Inc}Function InitADO( ConnectString : WideString ) : TADOConnect; Stdcall;implementation{ TADOConnect }Constructor TADOConnect.Create( ConnectString : WideString );
begin
Inherited Create;
CoInitialize( Nil );
FConnectString := ConnectString;
FADO := TADOConnection.Create( Nil );
FADO.ConnectionString := FConnectString;
FADO.LoginPrompt := False;
end;Destructor TADOConnect.Destroy;
Begin
FADO.Free;
CoUninitialize;
Inherited Destroy;
End;Function TADOConnect.Open : Boolean;
Begin
Try
FADO.Open;
Result := True;
Except
Result := False;
End;
End;Function TADOConnect.Close : Boolean;
Begin
Try
FADO.Close;
Result := True;
Except
Result := False;
End;
End;Function TADOConnect.GetConnection : TADOConnection;
Begin
Result := FADO;
End;Procedure TADOConnect.GetTableNames( Var List : TStringList; IncludeSysTable : Boolean );
Begin
If FADO.Connected Then FADO.GetTableNames( List, IncludeSysTable );
End;Procedure TADOConnect.GetFieldNames( Const TableName : String; Var List : TStringList );
Begin
If FADO.Connected Then FADO.GetFieldNames( TableName, List );
End;Procedure TADOConnect.GetProcedureNames( Var List : TStringList );
Begin
If FADO.Connected Then FADO.GetProcedureNames( List );
End;Function TADOConnect.GetConnectState : Boolean;
Begin
Result := FADO.Connected;
End;Function InitADO( ConnectString : WideString ) : TADOConnect;
Begin
Result := TADOConnect.Create( ConnectString );
End;end.Ado.Inc
Type
TADOConnect = Class( TObject )
{$IFDEF ADOCONNECT}
Private
FConnectString : WideString;
FADO : TADOConnection;
{$ENDIF}
Public
{$IFDEF ADOCONNECT}
Constructor Create( ConnectString : WideString );
Destructor Destroy; Override;
{$ENDIF}
Function Open : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Function Close : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Function GetConnection : TADOConnection; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Function GetConnectState : Boolean; Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Procedure GetTableNames( Var List : TStringList; IncludeSysTable : Boolean = False ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Procedure GetFieldNames( Const TableName : String; Var List : TStringList ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
Procedure GetProcedureNames( Var List : TStringList ); Virtual; Stdcall; {$IFNDEF ADOCONNECT} Abstract; {$ENDIF}
End;ADo.Dpr
library ADO;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes,
Main in 'Main.pas';{$R *.res}Exports
InitADO;
End.
To:hehou(嘿呵):听君一席言,有醍醐灌顶之感...
还希望各位多多指点!!