在某些场景下当轻量级的应用需要在内存中缓存数量比较多且字段比较多的高频使用数据时。以前我都是采用Ini或直接使用sqlite数据库。JSON也试过基本无法或很难实现需要的功能,因为当涉及某一同类型对象多字段多列时不通过遍历基本无法直接取到或修改数据。这样就导致了效率的低下。比如你在写一个多任务多线程并发断点续传下载工具的时候,就意味着要同时保存每个下载任务N个线程的不同状态和位置数据。并在关闭后持久化到磁盘。然后重新加载。最近发现FDMemTable真的是个好东西。非常好用。也轻量级。不像ClientDataSet还需要Midas.dll才能工作,简单记录一下
1 unit Unit1; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, 8 FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param, 9 FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, 10 Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.Grids, Vcl.DBGrids,Math 11 ; 12 13 type 14 TForm1 = class(TForm) 15 ListView1: TListView; 16 Label1: TLabel; 17 edtThreadCount: TEdit; 18 Label2: TLabel; 19 edtFileSize: TEdit; 20 Button8: TButton; 21 FDMemTable1: TFDMemTable; 22 Button1: TButton; 23 Button2: TButton; 24 DBGrid1: TDBGrid; 25 DataSource1: TDataSource; 26 Button3: TButton; 27 Label3: TLabel; 28 procedure Button1Click(Sender: TObject); 29 procedure Button2Click(Sender: TObject); 30 procedure Button8Click(Sender: TObject); 31 procedure Button3Click(Sender: TObject); 32 private 33 { Private declarations } 34 35 {内存表操作} 36 function GetIntByKey(IdkeyName:string; IdNo:Integer; KeyName:string):Integer; 37 function GetStrByKey(IdkeyName:string; IdNo: Integer;KeyName:string): string; 38 function SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue:Integer): Boolean; overload; 39 function SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: string): Boolean; overload; 40 41 { 42 function GetIntByKey(IdNo:Integer; KeyName:string):Integer; 43 function GetStrByKey(IdNo: Integer;KeyName:string): string; 44 function SetDataByKey(IdNo: Integer; KeyName: string; NewValue:Int64): Boolean; overload; 45 function SetDataByKey(IdNo: Integer; KeyName1: string; NewValue1: Int64; KeyName2: string; NewValue2: Int64): Boolean; overload; 46 function SetDataByKey(IdNo: Integer; KeyName: string; NewValue: string): Boolean; overload; 47 } 48 public 49 { Public declarations } 50 end; 51 52 Const 53 StartId: Integer = 100; //线程起始编号 54 IdKey: string = 'ThreadId'; //线程编号字段名 55 56 var 57 Form1: TForm1; 58 59 implementation 60 61 {$R *.dfm} 62 63 64 procedure TForm1.Button1Click(Sender: TObject); 65 var 66 FileSize,avg,aPos:Int64; 67 ThreadCount,ThreadID,i:Integer; 68 69 70 begin 71 if FDMemTable1.Active then 72 FDMemTable1.Close; 73 74 {定义表结构} 75 with FDMemTable1.FieldDefs do 76 begin 77 Clear; 78 Add('ThreadId', ftInteger, 0, True); 79 Add('Start', ftInteger, 0, True); 80 Add('End', ftInteger, 0, True); 81 Add('Length', ftInteger, 0, False); 82 Add('Current', ftInteger, 0, False); 83 Add('Status', ftInteger, 0, False); 84 Add('UsedTime', ftInteger, 0, False); 85 Add('LastTime', ftDateTime, 0, False); 86 Add('Speed', ftFloat, 0, False); 87 end; 88 89 {定义索引:非必须} 90 with FDMemTable1.IndexDefs do 91 begin 92 Clear; 93 Add('Index1', 'ThreadId', []); //定义索引 正序 94 //Add('Index1', 'ThreadId', [ixDescending]); //定义索引 倒序 95 end; 96 97 FDMemTable1.CreateDataSet; 98 99 {生成测试数据} 100 101 for i := 1 to 15 do 102 begin 103 FDMemTable1.AppendRecord([i, 1000 +i,1000 +i+100,10000,10000,0,0, Now(),58.9]); 104 end; 105 106 107 108 { Json格式写法 109 While aPos<FileSize do 110 begin 111 ThreadInfo:= TJSONObject.Create 112 .AddPair('ThreadID',StartId+i) 113 .AddPair('Start',aPos) 114 .AddPair('End',Min(aPos+avg, FileSize-1)) 115 .AddPair('Length',Min(aPos+avg, FileSize-1)-aPos) 116 .AddPair('Current',0) 117 .AddPair('Status',0); 118 JsonThread.Add(ThreadInfo); 119 Inc(i); 120 aPos:=aPos+avg+1; 121 end; 122 } 123 124 125 end; 126 127 procedure TForm1.Button2Click(Sender: TObject); 128 var 129 Item : TListItem; 130 begin 131 ListView1.Items.Clear; 132 FDMemTable1.First; 133 while (not FDMemTable1.Eof) do 134 begin 135 Item := ListView1.Items.Add; 136 Item.Caption := FDMemTable1.fieldByName('ThreadId').AsString; 137 Item.SubItems.Add(FDMemTable1.fieldByName('Start').AsString); 138 Item.SubItems.Add(FDMemTable1.fieldByName('End').AsString); 139 Item.SubItems.Add(FDMemTable1.fieldByName('Length').AsString); 140 Item.SubItems.Add(FDMemTable1.fieldByName('Current').AsString); 141 Item.SubItems.Add(FDMemTable1.fieldByName('Status').AsString); 142 Item.SubItems.Add(FDMemTable1.fieldByName('UsedTime').AsString); 143 Item.SubItems.Add(FDMemTable1.fieldByName('LastTime').AsString); 144 Item.SubItems.Add(FDMemTable1.fieldByName('Speed').AsString); 145 146 FDMemTable1.Next; 147 end; 148 149 FDMemTable1.First; 150 151 end; 152 153 154 {查询:返回Integer} 155 function TForm1.GetIntByKey(IdkeyName: string; IdNo: Integer; KeyName: string): Integer; 156 begin 157 Result := 0; 158 with FDMemTable1 do 159 begin 160 Open; 161 if Locate(IdkeyName, IdNo, []) then 162 Result := FieldByName(KeyName).AsInteger; 163 end; 164 end; 165 166 {查询:返回string} 167 function TForm1.GetStrByKey(IdkeyName: string; IdNo: Integer; KeyName: string): string; 168 begin 169 Result := ''; 170 with FDMemTable1 do 171 begin 172 Open; 173 if Locate(IdkeyName, IdNo, []) then 174 Result := FieldByName(KeyName).AsString; 175 end; 176 end; 177 178 179 {修改:Integer类型} 180 function TForm1.SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: Integer): Boolean; 181 begin 182 Result := False; 183 try 184 with FDMemTable1 do 185 begin 186 Open; 187 if Locate(IdkeyName, IdNo, []) then 188 begin 189 Edit; 190 FieldByName(KeyName).AsInteger := NewValue; 191 Post; 192 end; 193 Result := True 194 end; 195 except on E: Exception do 196 ShowMessage(e.Message); 197 end; 198 end; 199 200 {修改:string类型} 201 function TForm1.SetDataByKey(IdkeyName: string; IdNo: Integer; KeyName: string; NewValue: string): Boolean; 202 begin 203 Result := False; 204 try 205 with FDMemTable1 do 206 begin 207 Open; 208 if Locate(IdkeyName, IdNo, []) then 209 begin 210 Edit; 211 FieldByName(KeyName).AsString:= NewValue; 212 Post; 213 end; 214 Result := True 215 end; 216 except on E: Exception do 217 ShowMessage(e.Message); 218 end; 219 end; 220 221 procedure TForm1.Button8Click(Sender: TObject); 222 var 223 fld_Id: TIntegerField; 224 fld_Value: TStringField; 225 fld_Time: TDateTimeField; 226 begin 227 // Result:=0; 228 //FDMemTable1.Filter := Format('ThreadId=%d',[ID]); 229 //FDMemTable1.Filtered := True; 230 //Result:=FDMemTable1.FieldByName(KeyName).AsInteger 231 232 //查询 233 //with FDMemTable1 do 234 //begin 235 //Open; 236 //fld_Id := TIntegerField(FieldByName('End')); 237 fld_Value := TStringField(FieldByName('Value')); 238 fld_Time := TDateTimeField(FieldByName('Time')); 239 //if Locate('ThreadId', 12, []) then 240 //ShowMessage(fld_Id.AsString); 241 ShowMessage(GetIntByKey('ThreadId',108,'End').ToString); 242 end; 243 244 procedure TForm1.Button3Click(Sender: TObject); 245 begin 246 SetDataByKey('ThreadId',108,'End',8888); 247 end; 248 249 250 end.
测试程序效果如下:
一句话总结:是真的很好用,轻量高效稳定!YYDS
标签:function,封装,string,FireDAC,Delphi,IdNo,FDMemTable,Add,Integer From: https://www.cnblogs.com/bumpkin/p/17321036.html