Delphi FDMemTable内存表用法及简单操作函数封装

在某些场景下当轻量级的应用需要在内存中缓存数量比较多且字段比较多的高频使用数据时。以前我都是采用Ini或直接使用sqlite数据库。JSON也试过基本无法或很难实现需要的功能,因为当涉及某一同类型对象多字段多列时不通过遍历基本无法直接取到或修改数据。这样就导致了效率的低下。比如你在写一个多任务多线程并发断点续传下载工具的时候,就意味着要同时保存每个下载任务N个线程的不同状态和位置数据。并在关闭后持久化到磁盘。然后重新加载。最近发现FDMemTable真的是个好东西。非常好用。也轻量级。不像ClientDataSet还需要Midas.dll才能工作,简单记录一下

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.Grids, Vcl.DBGrids,Math
;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Label1: TLabel;
    edtThreadCount: TEdit;
    Label2: TLabel;
    edtFileSize: TEdit;
    Button8: TButton;
    FDMemTable1: TFDMemTable;
    Button1: TButton;
    Button2: TButton;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    Button3: TButton;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }

    {内存表操作}
    function GetIntByKey(IdkeyName:string; IdNo:Integer; KeyName:string):Integer;
    function GetStrByKey(IdkeyName:string; IdNo: Integer;KeyName:string): string;
    function SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue:Integer): Boolean; overload;
    function SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: string): Boolean; overload;

{
    function GetIntByKey(IdNo:Integer; KeyName:string):Integer;
    function GetStrByKey(IdNo: Integer;KeyName:string): string;
    function SetDataByKey(IdNo: Integer; KeyName: string; NewValue:Int64): Boolean; overload;
    function SetDataByKey(IdNo: Integer; KeyName1: string; NewValue1: Int64; KeyName2: string; NewValue2: Int64): Boolean; overload;
    function SetDataByKey(IdNo: Integer; KeyName: string; NewValue: string): Boolean; overload;
}
  public
    { Public declarations }
  end;

  Const
    StartId: Integer  = 100;     //线程起始编号
    IdKey: string = 'ThreadId';  //线程编号字段名

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
  FileSize,avg,aPos:Int64;
  ThreadCount,ThreadID,i:Integer;


begin
  if FDMemTable1.Active then
    FDMemTable1.Close;

  {定义表结构}
  with FDMemTable1.FieldDefs do
  begin
    Clear;
    Add('ThreadId', ftInteger, 0, True);
    Add('Start', ftInteger, 0, True);
    Add('End', ftInteger, 0, True);
    Add('Length', ftInteger, 0, False);
    Add('Current', ftInteger, 0, False);
    Add('Status', ftInteger, 0, False);
    Add('UsedTime', ftInteger, 0, False);
    Add('LastTime', ftDateTime, 0, False);
    Add('Speed', ftFloat, 0, False);
  end;

  {定义索引:非必须}
  with FDMemTable1.IndexDefs do
  begin
    Clear;
    Add('Index1', 'ThreadId', []); //定义索引 正序
   //Add('Index1', 'ThreadId', [ixDescending]); //定义索引 倒序
  end;

  FDMemTable1.CreateDataSet;

   {生成测试数据}

 for i := 1 to 15 do
  begin
    FDMemTable1.AppendRecord([i, 1000 +i,1000 +i+100,10000,10000,0,0, Now(),58.9]);
  end;



{  Json格式写法
  While aPos<FileSize do
  begin
    ThreadInfo:= TJSONObject.Create
        .AddPair('ThreadID',StartId+i)
        .AddPair('Start',aPos)
        .AddPair('End',Min(aPos+avg, FileSize-1))
        .AddPair('Length',Min(aPos+avg, FileSize-1)-aPos)
        .AddPair('Current',0)
        .AddPair('Status',0);
     JsonThread.Add(ThreadInfo);
     Inc(i);
     aPos:=aPos+avg+1;
  end;
 }


end;

procedure TForm1.Button2Click(Sender: TObject);
var
   Item : TListItem;
begin
   ListView1.Items.Clear;
   FDMemTable1.First;
   while (not FDMemTable1.Eof) do
      begin
         Item := ListView1.Items.Add;
         Item.Caption := FDMemTable1.fieldByName('ThreadId').AsString;
         Item.SubItems.Add(FDMemTable1.fieldByName('Start').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('End').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('Length').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('Current').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('Status').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('UsedTime').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('LastTime').AsString);
         Item.SubItems.Add(FDMemTable1.fieldByName('Speed').AsString);

         FDMemTable1.Next;
      end;

   FDMemTable1.First;

end;


{查询:返回Integer}
function TForm1.GetIntByKey(IdkeyName: string; IdNo: Integer; KeyName: string): Integer;
begin
  Result := 0;
  with FDMemTable1 do
  begin
    Open;
    if Locate(IdkeyName, IdNo, []) then
      Result := FieldByName(KeyName).AsInteger;
  end;
end;

{查询:返回string}
function TForm1.GetStrByKey(IdkeyName: string; IdNo: Integer; KeyName: string): string;
begin
  Result := '';
  with FDMemTable1 do
  begin
    Open;
    if Locate(IdkeyName, IdNo, []) then
      Result := FieldByName(KeyName).AsString;
  end;
end;


{修改:Integer类型}
function TForm1.SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: Integer): Boolean;
begin
  Result := False;
  try
    with FDMemTable1 do
    begin
      Open;
      if Locate(IdkeyName, IdNo, []) then
      begin
        Edit;
        FieldByName(KeyName).AsInteger := NewValue;
        Post;
      end;
      Result := True
    end;
  except on E: Exception do
      ShowMessage(e.Message);
  end;
end;

{修改:string类型}
function TForm1.SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: string): Boolean;
begin
  Result := False;
  try
    with FDMemTable1 do
    begin
      Open;
      if Locate(IdkeyName, IdNo, []) then
      begin
        Edit;
        FieldByName(KeyName).AsString:= NewValue;
        Post;
      end;
      Result := True
    end;
  except on E: Exception do
      ShowMessage(e.Message);
  end;
end;

procedure TForm1.Button8Click(Sender: TObject);
var
  fld_Id: TIntegerField;
  fld_Value: TStringField;
  fld_Time: TDateTimeField;
begin
//  Result:=0;
  //FDMemTable1.Filter := Format('ThreadId=%d',[ID]);
  //FDMemTable1.Filtered := True;
  //Result:=FDMemTable1.FieldByName(KeyName).AsInteger

//查询
//with FDMemTable1 do
//begin
//Open;
//fld_Id := TIntegerField(FieldByName('End'));
fld_Value := TStringField(FieldByName('Value'));
fld_Time := TDateTimeField(FieldByName('Time'));
//if Locate('ThreadId', 12, []) then
//ShowMessage(fld_Id.AsString);
 ShowMessage(GetIntByKey('ThreadId',108,'End').ToString);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  SetDataByKey('ThreadId',108,'End',8888);
end;


end.

测试程序效果如下:

 一句话总结是真的很好用,轻量高效稳定!YYDS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值