// Writen by 咏南工作室(陈新光) 2009-6-26 14:31:26
{ for example:
var
q: TADOQuery;
begin
Result := nil;
q := g_adoquerypool.GetAdoQuery;
if q <> nil then
begin
q.Close;
q.SQL.Clear;
q.SQL.Text := sqlCommand;
q.Open;
Result := q;
g_adoquerypool.returnAdoQuery(q);
end;
}
unit AdoQueryPool;
{$HINTS OFF}
{$WARNINGS OFF}
interface
uses
SysUtils, Classes, DB, ADODB, Contnrs, Windows, ExtCtrls,forms;
type
TAdoQueryPool = class(TComponent) // adoQuery对象池类
private
fAdoQueryMin: Integer; // 对象池最小保留adoQuery数量
fAdoQueryMax: Integer; // 对象池最大可拥有adoQuery数量
fRefreshTime: Integer; // 定时轮询对象池的时间
fTimeOut: Integer; // 非使用中对象超时时间
fTimeOut2: Integer; // 使用中对象超时时间
fAdoQueryList: TComponentList; // 对象容器
fCleanTimer: TTimer;
procedure fCleanOnTime(sender: TObject); // 定时轮询对象池方法
function fCreateADOQuery: TADOQuery;
procedure fClean;
function GetPoolSize:Integer;
{ Private declarations }
public
{ Public declarations }
constructor Create;
destructor Destroy; override;
function GetAdoQuery: TADOQuery; // 获取对象池内非使用中对象
procedure returnAdoQuery(qry: TADOQuery); // 使用完的对象归还对象池内
property PoolSize: Integer read GetPoolSize;
property PoolMin: Integer read fAdoQueryMin;
property PoolMax: Integer read fAdoQueryMax;
property PoolForTime: Integer read fRefreshTime;
property PoolNoUseObjTimeOut: Integer read fTimeOut;
property PoolInUseObjTimeOut: Integer read fTimeOut2;
end;
implementation
{ TAdoQueryPool }
constructor TAdoQueryPool.Create;
var
index: Integer;
begin
fAdoQueryMin := 10;
fAdoQueryMax := 500;
fRefreshTime := 3000;
fTimeOut := 5000;
fTimeOut2 := 1800000;
fAdoQueryList := TComponentList.Create(False); // 创建对象容器
fCleanTimer := TTimer.Create(Self);
fCleanTimer.Name := 'MyCleanTimer1';
fCleanTimer.Interval :=fRefreshTime;
fCleanTimer.OnTimer := fCleanOnTime;
fCleanTimer.Enabled := True;
end;
destructor TAdoQueryPool.Destroy;
var
i: integer;
begin
for i := fAdoQueryList.Count - 1 downto 0 do
TADOQuery(fAdoQueryList[i]).Free;
fAdoQueryList.Free;
fAdoQueryList := nil;
inherited;
end;
procedure TAdoQueryPool.fClean;
var
iNow : Integer;
index : Integer;
begin
iNow := GetTickCount; // 获取当前时间
for index := fAdoQueryList.Count - 1 downto 0 do // 轮询对象池
begin
if TADOQuery(fAdoQueryList[index]).Tag > 0 then // 非使用中对象
begin
if fAdoQueryList.Count > fAdoQueryMin then // 对象池内对象总数 > 对象池最小对象保留数量
if iNow - TADOQuery(fAdoQueryList[index]).Tag > fTimeOut then // 超时
TADOQuery(fAdoQueryList[index]).Free;
end
else if TAdoQuery(fAdoQueryList[index]).Tag < 0 then // 使用中对象
begin
if iNow + TADOQuery(fAdoQueryList[index]).Tag > ftimeOut2 then // 超时
begin
TADOQuery(fAdoQueryList[index]).Free; // 释放对象
if fAdoQueryList.Count < fAdoQueryMin then // 对象池对象总数 < 对象池最小保留对象
fAdoQueryList.Add(fCreateADOQuery); // 对象池内创建新对象
end;
end;
end;
end;
procedure TAdoQueryPool.fCleanOnTime(sender: TObject);
begin
fClean;
end;
function TAdoQueryPool.fCreateADOQuery: TADOQuery;
begin
Result := TADOQuery.Create(Self);
Result.Tag := GetTickCount;
Result.ConnectionString := 'FILE NAME='+extractfilepath(Application.ExeName)+'connect.udl';
end;
function TAdoQueryPool.GetAdoQuery: TADOQuery;
var
index: Integer;
begin
Result := nil;
if fAdoQueryList.Count = 0 then //池中没有任何对象
begin
Result := fCreateADOQuery; // 创建新对象
Result.Tag := - GetTickCount; // 标记为使用中
fAdoQueryList.Add(Result); // 放入对象池内
Exit;
end;
for index := 0 to fAdoQueryList.Count - 1 do // 轮询对象池
begin
if TADOQuery(fAdoQueryList[index]).Tag > 0 then // 非使用中对象
begin
Result := TADOQuery(fAdoQueryList[index]);
Result.Tag := - GetTickCount; // 标记为使用中
Break;
end;
end;
if (Result = nil) and (index < fAdoQueryMax) then // 对象池内已经没有非使用中对象
begin
Result := fCreateADOQuery; // 创建新对象
Result.Tag := - GetTickCount; // 标记为使用中
fAdoQueryList.Add(Result); // 放入对象池内
end;
end;
function TAdoQueryPool.GetPoolSize: Integer;
begin
Result := fAdoQueryList.Count;
end;
procedure TAdoQueryPool.returnAdoQuery(qry: TADOQuery);
begin
if fAdoQueryList.IndexOf(qry) <> -1 then
qry.Tag := GetTickCount; // 标记为非使用中对象
end;
end.