TManagedDataSet和DataSetPool的实现 (转)

TManagedDataSet和DataSetPool的实现 (转)[@more@]

TManagedDataSet和DataSetPool的实现XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

  天天用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.


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10748419/viewspace-960621/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10748419/viewspace-960621/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值