• TADOConnection池


    //==============================================================================
    // TADOConnection池   咏南工作室(陈新光)   2008-10-06 14:00:23
    //==============================================================================

    unit UDataConnPool;

    interface

    uses
      SysUtils, Classes, DB, ADODB, Contnrs, Windows, ExtCtrls;

    const//ole db provider
      c_sql='sqloledb';
      c_access='microsoft.jet.oledb.4.0';
      c_oracle='MSDAORA.1';

    type// 数据库类型
      TDBType=(Access,SqlServer,Oracle);

    type//连接池参数
      RConnParameter=record
        ConnMin:Integer;      //池中对象的最小数
        ConnMax:Integer;      //池中对象的最大数
        TimeOut:Integer;      //空闲连接超时  600000(10分钟)
        TimeOut2:Integer;     //占用连接超时  3600000(1小时)
        RefreshTime:Integer;  //秒,轮询池的时间间隔
        dbSource:string;      //数据源
        DB:string;            //sql server连接时需要数据库名参数
        dbUser:string;        //登录数据库的用户名
        dbPass:string;        //用户密码
        dbpass2:string;       //Access可能需要数据库密码
      end;

    type
      TDataConnectionPool = class(TComponent)      //数据库连接池类
      private
        fConnParameter : RConnParameter;
        fConnList : TComponentList;
        fCleanTimer : TTimer;
        fDBType: TDBType;
        procedure fCleanOnTime(sender : TObject);
        function fCreateADOConn : TADOConnection;  //创建新的空闲连接
        procedure fClean;                          //清理 (清理长时间不用的和长时间不归还的(死的)连接)
        { Private declarations }
      protected
        function getConnCount: Integer;
      public
        { Public declarations }
        property ConnCount: Integer read getConnCount;
        constructor Create(owner : TComponent; connParam: RConnParameter;dbType:TDBType);overload;
        function getConn : TADOConnection;             //取得空闲连接
        procedure returnConn(conn : TADOConnection);   //归还连接
    end;

    implementation

    //connParam(连接池参数)   dbType(数据库类型)
    constructor TDataConnectionPool.Create(owner : TComponent; connParam: RConnParameter;dbType:TDBType);
    var
      index: Integer;
    begin
      inherited Create(owner);
      fDBType:=dbType;

      fConnParameter.ConnMin := connParam.ConnMin;
      fConnParameter.ConnMax := connParam.ConnMax;
      fConnParameter.TimeOut:=connParam.TimeOut;
      fConnParameter.TimeOut2:=connParam.TimeOut2;
      fConnParameter.RefreshTime := connParam.RefreshTime;
      fConnParameter.dbUser := connParam.dbUser;
      fConnParameter.dbPass := connParam.dbPass;
      fConnParameter.dbpass2:=connParam.dbpass2;    
      fConnParameter.dbSource := connParam.dbSource;
      fConnParameter.DB:=connParam.DB;

      if fConnList = nil then
      begin
        fConnList := TComponentList.Create;         //池容器 TComponentList
        for index := 1 to fConnParameter.ConnMin do //创最小连接个数个建数据库连接
          fConnList.Add(fCreateADOConn);
      end;

      if fCleanTimer = nil then                     //清理程序启动的时间间隔
      begin
        fCleanTimer := TTimer.Create(Self);
        fCleanTimer.Name := 'MyCleanTimer1';
        fCleanTimer.Interval := fConnParameter.RefreshTime * 1000;
        fCleanTimer.OnTimer := fCleanOnTime;
        fCleanTimer.Enabled := True;
      end;
    end;

    procedure TDataConnectionPool.fClean;
    var
      iNow : Integer;
      iCount : Integer;
      index : Integer;
    begin
      iNow := GetTickCount;
      iCount := fConnList.Count;
      for index := iCount - 1 downto 0 do
      begin
        if TADOConnection(fConnList[index]).Tag > 0 then                                //空闲连接
        begin
          if fConnList.Count > fConnParameter.ConnMin then
          begin                                                                         //空闲时间=当前时间-最后活动时间
            if iNow - TADOConnection(fConnList[index]).Tag > fConnParameter.TimeOut then//超过10分钟不使用的、大于连接池最小数目的空闲连接将被释放
              fConnList.Delete(index);
          end;
        end
        else if TADOConnection(fConnList[index]).Tag < 0 then                           //占用连接
        begin
          if iNow + TADOConnection(fConnList[index]).Tag > fConnParameter.TimeOut2 then //被连续使用超过1小时的连接(很可能是死连接将被)释放
          begin
            fConnList.Delete(index);
            if fConnList.Count < fConnParameter.ConnMin then                            //若小于连接池最小数目,则创建新的空闲连接
              fConnList.Add(fCreateADOConn);
          end;
        end
      end;
    end;

    procedure TDataConnectionPool.fCleanOnTime(sender: TObject);
    begin
      fClean;
    end;

    function TDataConnectionPool.fCreateADOConn: TADOConnection;
    var
      conn:TADOConnection;
    begin
      Conn:=TADOConnection.Create(Self);
      with conn do
      begin
        LoginPrompt:=False;
        Tag:=GetTickCount;

        case fDBType of
          sqlserver:
          begin
            Provider:=c_sql;
            Properties['Data Source'].Value:=fConnParameter.dbSource;
            Properties['User ID'].Value:=fConnParameter.dbUser;
            Properties['Password'].Value:=fConnParameter.dbPass;
            Properties['Initial Catalog'].Value:=fConnParameter.DB;
          end;

          access:
          begin
            Provider:=c_access;
            Properties['Jet OLEDB:Database Password'].Value:=fConnParameter.dbPass2;
            Properties['Data Source'].Value:=fConnParameter.dbSource;
            Properties['User ID'].Value:=fConnParameter.dbUser;
            Properties['Password'].Value:=fConnParameter.dbPass;
          end;

          oracle:
          begin
            Provider:=c_oracle;
            Properties['Data Source'].Value:=fConnParameter.dbSource;
            Properties['User ID'].Value:=fConnParameter.dbUser;
            Properties['Password'].Value:=fConnParameter.dbPass;
          end;
        end;

        try
          Connected:=True;
          Result:=conn;
        except
          Result:=nil;
          raise Exception.Create('数据库连接失败');
        end;
      end;
    end;

    function TDataConnectionPool.getConn: TADOConnection;
    var
      index : Integer;
    begin
      Result := nil;
      for index := 0 to fConnList.Count - 1 do
      begin
        if TADOConnection(fConnList[index]).Tag > 0 then
        begin
          Result := TADOConnection(fConnList[index]);
          Result.Tag := - GetTickCount;                          //使用开始计时 (负数表示正在使用
        end;
      end;

      if (Result = nil) and (index < fConnParameter.ConnMax) then//无空闲连接,而连接池数目小于允许最大数目(fMax),创建新的连接
      begin
        Result := fCreateADOConn;
        Result.Tag := - GetTickCount;                            //使用,开始计时 (负数表示正在使用)
        fConnList.Add(Result);
      end;
    end;

    function TDataConnectionPool.getConnCount: Integer;
    begin
      Result := fConnList.Count;
    end;

    procedure TDataConnectionPool.returnConn(conn: TADOConnection);
    begin
      if fConnList.IndexOf(conn) > -1 then
        conn.Tag := GetTickCount;
    end;

    end.

  • 相关阅读:
    java 数据类型:集合接口Collection之List~ArrayList:remove移除;replaceAll改变原有值;sort排序;迭代器listIterator();
    java 数据类型:集合接口Collection之常用ArrayList;lambda表达式遍历;iterator遍历;forEachRemaining遍历;增强for遍历;removeIf批量操作集合元素(Predicate);
    java 常用类库:格式化NumberFormat;SimpleDataFormat类(转换Data()对象);DateTimeFormatter 转换LocalDateTime时间对象
    java 常用类库:时间类LocalDate;LocalTime;LocalDateTime;Calendar 类;Date ;
    java 常用类库:BigInteger大整数;BigDecimal大小数(解决double精度损失);
    java 常用类库:Math:常用min、max;floor;ceil;random;
    1345. Jump Game IV
    1298. Maximum Candies You Can Get from Boxes
    1293. Shortest Path in a Grid with Obstacles Elimination
    1263. Minimum Moves to Move a Box to Their Target Location
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940809.html
Copyright © 2020-2023  润新知