WEB开发网
开发学院软件开发Delphi TManagedDataSet和DataSetPool的实现 阅读

TManagedDataSet和DataSetPool的实现

 2006-02-04 13:41:17 来源:WEB开发网   
核心提示:TManagedDataSet和DataSetPool的实现 天天用Delphi,自己有了很多想法,TManagedDataSet和DataSetPool的实现,写代码之余,有空闲时间就把一些东西整理成文档, 下面的代码是直接从我做的一个项目的源文件中Copy出来的,有些乱, Delphi中使用最多的大概是AdoEx
TManagedDataSet和DataSetPool的实现        天天用Delphi,自己有了很多想法。写代码之余,有空闲时间就把一些东西整理成文档。      Delphi中使用最多的大概是AdoExPRess组件,这是Borland封装了Microsoft的Ado的东东,使用频率最多的TAdoDataSet对应了Ado原生的RecordSet,在功能上做了一些增强,但用法基本一致,用多了就感觉TAdoDataSet还有扩充和改造的地方。      由于代码中使用了很多的TAdoDataSet控件,创建和释放对象非常频繁,而且每次创建后都要设置很多基本相同的属性,颇为麻烦。于是想到可以实现一个记录集池,每次当需要一个记录集时,从这个池中得到一个空闲且符合要求的(只读或可读写),用完了就被池回收,如果池中记录集不够,就自动生成新的记录集对象。      首先要做的是改造TAdoDataSet,我写了一个TManagedDataSet,继承自TAdoDataSet,可以自己知道自己是被人使用还是空闲(通过IsUsed()),重写了Free(),把本来释放的动作改为仅是把自己设置为空闲,并清除状态(session)信息,并可以通过Source()返回一个指向自己的TDataSource对象。      有了这些基础后,就可以很快的构建TDataSetPool类了,这个类仅是保存可用的TManagedDataSet对象,通过GetDataSet(WantType : TManagedDataSetType)返回一个空闲的数据集对象,如果池中没有空闲的,就新建一个返回。TManagedDataSetType是枚举类,标识只读数据集和读写数据集(只读数据集可通过优化CursorType和LockType来加快读数据速度)。      下面的代码是直接从我做的一个项目的源文件中Copy出来的,有些乱,仅做参考。       unit ManagedDataSet;   interface   uses AdoDb, CommonDm, SysUtils, DB, dbgrids, ComObj, classes, contnrs;   type      TManagedDataSetType = (ReadOnly, Editable); // 猅羭摸    TXlsExpAdapter = class      private        _sXlsCaption : string;        _sXlsFileName : string;        _bOverwriteExistFile : Boolean;                _asFieldName : TStringList;        _asXlsTitle : TStringList;        _aDataType : TObjectList;        function GetDataType(const iniIndex : Integer) : TDataType;        function GetFieldName(const iniIndex : Integer) : string;        function GetXlsTitle(const iniIndex : Integer) : string;      public        constructor Create();        destructor Destroy();        property XlsCaption : string read _sXlsCaption Write _sXlsCaption;        property XlsFileName : string read _sXlsFileName Write _sXlsFileName;        property OverWriteExistFile : Boolean read _bOverwriteExistFile Write _bOverwriteExistFile;                procedure AddField(const insFieldName, insCaption : string; const intype : TDataType = ftUnKnown);        procedure GetInfoFromDBGrid(const ingrid : TDBGrid);        property DataType[const iniIndex : Integer] : TDataType read GetDataType;        property FieldName[const iniIndex : Integer] : string read GetFieldName;        property XlsTitle[const iniIndex : Integer] : string read GetXlsTitle;        function Count() : Integer;    end;    TManagedDataSet = class(TAdoDataSet)           private        _source : TDataSource;        _type : TManagedDataSetType;        _bUsed : Boolean;          procedure SetDataSetType(const intype : TManagedDataSetType);        function GetDataSource() : TDataSource;      public        constructor Create(const intype : TManagedDataSetType = Editable);        destructor Destroy(); override;                procedure Use();        procedure Free(); reintroduce; // 滦护髅篎reeぃ穦睦龟ㄒ        property DataSetType : TManagedDataSetType read _type Write SetDataSetType;        property IsUsed : Boolean read _bUsed;        property Source : TDataSource read GetDataSource;        function ExportToXls(const inadapter : TXlsExpAdapter) : Boolean;    end;   implementation   function TXlsExpAdapter.Count() : Integer; begin    Result := _asFieldName.Count; end;   function TXlsExpAdapter.GetXlsTitle(const iniIndex : Integer) : string; begin      if (iniIndex >= 0) and (iniIndex <= _aDataType.Count-1) then    begin    Result := _asXlsTitle[iniIndex];    end; end;   function TXlsExpAdapter.GetFieldName(const iniIndex : Integer) : string; begin      if (iniIndex >= 0) and (iniIndex <= _aDataType.Count-1) then    begin    Result := _asFieldName[iniIndex];    end; end;   function TXlsExpAdapter.GetDataType(const iniIndex : Integer) : TDataType; begin    if (iniIndex >= 0) and (iniIndex <= _aDataType.Count-1) then    begin      Result := TDataType(_aDataType[iniIndex]);    end; end;   procedure TXlsExpAdapter.GetInfoFromDBGrid(const ingrid : TDBGrid); var      i, j : Integer;    dt : TDataType; begin      for i := 0 to ingrid.Columns.Count-1 do    begin           if ingrid.Columns[i].Visible then      begin        dt := ftUnknown;        for j := 0 to ingrid.FieldCount-1 do        begin          if ingrid.Columns[i].FieldName = ingrid.Fields[j].FieldName then          begin            dt := ingrid.Fields[j].DataType;            Break;          end;        end;        Self.AddField(ingrid.Columns[i].FieldName, ingrid.Columns[i].Title.Caption, dt);      end;    end;  end;   procedure TXlsExpAdapter.AddField(const insFieldName, insCaption : string; const intype : TDataType = ftUnKnown); var      iIndex : Integer; begin      iIndex := _asFieldName.IndexOf(insFieldName);    if iIndex = -1 then    begin      _asFieldName.Add(insFieldName);      _asXlsTitle.Add(insCaption);      _aDataType.Add(TObject(intype));    end    else begin      _asFieldName[iIndex] := insFieldName;      _asXlsTitle[iIndex] := insCaption;      _aDataType[iIndex] := TObject(intype);    end; end;   constructor TXlsExpAdapter.Create(); begin      _asFieldName := TStringList.Create();    _asXlsTitle := TStringList.Create();    _aDataType := TObjectList.Create(); end;   destructor TXlsExpAdapter.Destroy(); begin   end;   function TManagedDataSet.ExportToXls(const inadapter : TXlsExpAdapter) : Boolean; var      Excelobj : OleVariant;    i : Integer; begin      Result := False;         if not Self.Active then      Exit;        try    excelobj := CreateOleObject('Excel.application');      excelobj.WorkBooks.Add;    except    Exit;    end;      if FileExists(inadapter.XlsFileName) and inadapter.OverWriteExistFile then    begin      DeleteFile(PChar(inadapter.XlsFileName));    end    else begin      excelobj.Quit;      Exit;    end;      for i := 0 to inadapter.Count-1 do    begin              end; end;   constructor TManagedDataSet.Create(const intype : TManagedDataSetType = Editable); begin      inherited Create(nil);      Self.Connection := DmCommon.Cnn;    Self.CursorLocation := clUseClient;    Self.Prepared := True;    Self.CacheSize := 1000;    if intype = ReadOnly then    begin    Self.CursorType := ctOpenForwardOnly;    Self.LockType := ltReadOnly;    end    else if intype = Editable then    begin      Self.CursorType := ctStatic;    Self.LockType := ltOptimistic;    end;      _type := intype;    _bUsed := False; end;   destructor TManagedDataSet.Destroy(); begin      if Self.Active then    begin         Self.Close;    end;    if Assigned(_source) then    begin         FreeAndNil(_source);    end;    inherited Destroy(); end;   procedure TManagedDataSet.Use(); begin    if _bUsed then    begin      raise Exception.Create('Cannot get a used managed dataset !');    end;      _bUsed := True; end;   procedure TManagedDataSet.Free(); begin      if Self.Active then    begin    Self.Close;    end;      Self.CommandText := '';    Self.Parameters.Clear; // 睲埃把计    Self.MasterFields := ''; // 睲埃琿    Self.DataSource := nil;    Self.ExecuteOptions := []; // 睲埃磅︽匡兜    _bUsed := False; end;   procedure TManagedDataSet.SetDataSetType(const intype : TManagedDataSetType); begin    if intype = _type then    Exit;      if intype = ReadOnly then    begin    Self.CursorType := ctOpenForwardOnly;    Self.LockType := ltReadOnly;    end    else if intype = Editable then    begin      Self.CursorType := ctStatic;    Self.LockType := ltOptimistic;    end; end;   function TManagedDataSet.GetDataSource() : TDataSource; begin      if not Assigned(_source) then    begin         _source := TDataSource.Create(nil);    _source.AutoEdit := False;         _source.DataSet := Self;    end;    Result := _source; end;   end.           unit DataSetPool; // 癘魁栋GlobalVarい承セ摸Ы龟ㄒ跑秖   interface   uses ManagedDataSet, Contnrs, SysUtils, AdoDb, Db, CommonDm;   type      TDataSetPool = class           private        _ads : TObjectList;        function GetCount() : Integer;      public        constructor Create(const ini : Integer = 10);        destructor Destroy(); override;        property Count : Integer read GetCount;        function GetDataSet(const intype : TManagedDataSetType = Editable) : TManagedDataSet;        function GetAdoCommand() : TAdoCommand; // 度TAdoCommand睦パ秸ノ璽砫    end;   implementation   constructor TDataSetPool.Create(const ini : Integer = 10); begin      _ads := TObjectList.Create; end;   destructor TDataSetPool.Destroy(); begin    FreeAndNil(_ads); end;   function TDataSetPool.GetCount() : Integer; begin      Result := _ads.Count; end;   function TDataSetPool.GetDataSet(const intype : TManagedDataSetType = Editable) : TManagedDataSet; var      i : Integer; begin      Result := nil;        for i := 0  to _ads.Count-1 do    begin           if (not TManagedDataSet(_ads[i]).IsUsed) and (TManagedDataSet(_ads[i]).DataSetType = intype) then      begin        Result := TManagedDataSet(_ads[i]);        Result.Use;        break;      end;    end;      if Result = nil then    begin           _ads.Add(TManagedDataSet.Create(intype));      Result := TManagedDataSet(_ads[_ads.Count-1]);      Result.Use;    end; end;   function TDataSetPool.GetAdoCommand() : TAdoCommand; begin      Result := TADOCommand.Create(nil);    Result.Connection := DmCommon.Cnn; end;   end.

Tags:TManagedDataSet DataSetPool 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接