程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> TManagedDataSet和DataSetPool的實現

TManagedDataSet和DataSetPool的實現

編輯:Delphi
        天天用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;  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved