<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      TManagedDataSet與DataSetPool的完成

      [摘要]Delphi中使用最多的大概是AdoExpress組件,這是Borland封裝了Microsoft的Ado的東東,使用頻率最多的TAdoDataSet對應了Ado原生的RecordSet,在功能上做了一些增強,但用法基本一致,用多了就感覺TAdoDataSet還有擴充和改造的地方。 ...
               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; // 灤籠摸Freeぃ穦睦龜ㄒ

                  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.



      日韩精品一区二区三区高清