• adoQuery对象池


    // 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.

  • 相关阅读:
    有关ASP的过程及函数的定义方法及调用
    ASP留言板(在一页里实现所有功能)
    滚动DataGrid
    效果试验
    自己写的身份证号码15位升18位的函数
    [学习笔记]开始学directx了之一
    改写的一个自动生成图片验证码的类asp.net(vb)
    参加了腾讯通RTX客户交流会
    杨伟帆的个人简历
    全国省市县无刷新多级关联菜单
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940771.html
Copyright © 2020-2023  润新知