关于内存数据与 JSON

http://www.cnblogs.com/del/p/4225871.html

闲话:

正在用 WebBroker 写一个小网站,感受颇多:
1、如果是写一个小东西,应该先考虑下 WebBroker,因为它是分分钟即可上手的。
2、如果要写一个大东西,或许也应该考虑下 WebBroker,因为相比其他它有着最高的灵活度(但这只是想像,因为我只是写了一个小东西)。
3、Delphi 3 就有了 WebBroker,可惜现在才开始使用它;随着“服务器”与“网页程序”的普及,WebBroker 应该会被更多地提起。

期间用到了 json, 所以有了这篇博文。



Delphi 与内存数据的总结与回顾 :

1、普通类型变量:储存一个数据。

2、数组:储存一组同类型的数据。

3、结构体:储存一组不同类型的数据;现在的结构体越来越复杂了,还可以操作这些个数据,越来越像“类”了。

4、“键值”对:我一般使用 TStringList,并常常用它代替 ini 文件类;同类还有 THashedStringList、TStringHash。

5、分类的 “键值”对:TMemIniFile、TIniFile; 另外还有人用 sqlite 做了一个可以储存二进制数据的 ini 文件类(忘了名了),我试过,非常好用(在官方示例中)。

6、内存数据表:现在应该首选 TFDMemTable 了(之前是 TClientDataSet)。

7、数据库级别的内存(或文件)数据:SqLite。

8、内存多叉树:JSON(或 XML);之前一直使用 SuperObject,以后会使用 System.JSON 更多些。

System.JSON?还是 SuperObject?

System.JSON 是官方的;这省去很多麻烦,这也是我考虑它的主要原因。

System.JSON “读写文件” 与 “格式化” 等功能,都有的功能也不如 SuperObject 方便。

System.JSON 主要考虑的是:从服务器生成 json,然后传输到客户端(特别是给 JavaScript 使用),不像 SuperObject 大而全。

如果不是太复杂的 json 应用,优先考虑 System.JSON 吧;如果需要更多功能,SuperObject 会更理想。


1 分钟了解 System.JSON :

其中的类不少,主要用到的有:TJSONObject、TJSONArray。

uses System.JSON;

//TJSONObject
procedure TForm1.Button1Click(Sender: TObject);
var
  j: TJSONObject;
begin
  j := TJSONObject.Create;
  j.AddPair('aa', '111');
  j.AddPair('bb', '222');

  //输出字符串
  Memo1.Text := j.ToString; //结果:{"aa":"111","bb":"222"}
    {ToJSON 与 ToString 结果相同,但应尽量使用 ToString 而不是 ToJSON;因为 ToJSON 也是调用 ToString 并且还要重新分配内存}

  j.Free;
end;

//TJSONArray
procedure TForm1.Button2Click(Sender: TObject);
var
  a: TJSONArray;
begin
  a := TJSONArray.Create;
  a.Add(1); //TJSONArray 不像传统的数组,它可以接受几种不同类型的值;这应该算是对 Delphi 数组功能的扩充吧。
  a.Add(2);
  a.Add('aaa');
  a.Add('bbb');

  Memo1.Text := a.ToString; //结果:[1,2,"aaa","bbb"]

  a.Free;
end;

//当 TJSONObject 嵌套其他对象时
procedure TForm1.Button3Click(Sender: TObject);
var
  j: TJSONObject;
  a: TJSONArray;
begin
  j := TJSONObject.Create;
  a := TJSONArray.Create('aaa', 'bbb'); //可以使用两个值初始化
  a.Add(1);
  a.Add(2);

  j.AddPair('arr', a);

  Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}

//  a.Free; {千万不要释放其内部对象,它的父对象会自动释放它}
  j.Free;
end;

//变通上例
procedure TForm1.Button4Click(Sender: TObject);
var
  j: TJSONObject;
begin
  j := TJSONObject.Create;

  j.AddPair('arr', TJSONArray.Create);

  with j.Values['arr'] as TJSONArray do
  begin
    Add('aaa');
    Add('bbb');
    Add(1);
    Add(2);
  end;

  Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}
  j.Free;
end;

//再变通
procedure TForm1.Button5Click(Sender: TObject);
var
  j: TJSONObject;
  a: TJSONArray;
begin
  j := TJSONObject.Create;

  j.AddPair('arr', TJSONArray.Create);

  a := TJSONArray(j.Values['arr']);
  a.Add('aaa');
  a.Add('bbb');
  a.Add(1);
  a.Add(2);

  Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}
  j.Free;
end;

//添加其他类型的数
procedure TForm1.Button6Click(Sender: TObject);
var
  j: TJSONObject;
  a: TJSONArray;
begin
  j := TJSONObject.Create;
  j.AddPair('数值', TJSONNumber.Create(3.1415926));
  j.AddPair('布尔真', TJSONTrue.Create);
  j.AddPair('布尔假', TJSONFalse.Create);
  j.AddPair('空值', TJSONNull.Create);

  Memo1.Text := j.ToString; //结果:{"数值":3.1415926,"布尔真":true,"布尔假":false,"空值":null}
  j.Free;
end;

//读取
procedure TForm1.Button7Click(Sender: TObject);
var
  j: TJSONObject;
  str: string;
  num: Integer;
  arr1,arr2: string;
begin
  j := TJSONObject.Create;
  j.AddPair('str', '111');
  j.AddPair('num', TJSONNumber.Create(222));
  j.AddPair('arr', TJSONArray.Create('arr1', 'arr2'));

  Memo1.Text := j.ToString; //结果:{"str":"111","num":222,"arr":["arr1","arr2"]}

  //JSON 是一组”键值对“,其中的”值“还有可能是”键值对“;
  //所以 System.JSON 用 TJSONValue 来表示值类型,它是所有值类型的父类,当然也是 TJSONObject 的父类。

  str := j.Values['str'].Value;             //Values[] 调用的是 GetValue(), 更喜欢直接用后者
  num := j.GetValue('num').Value.ToInteger;

  arr1 := TJSONArray(j.GetValue('arr')).Items[0].Value;
  arr2 := TJSONArray(j.GetValue('arr')).Items[1].Value;

  Memo1.Lines.Add(Format('%s, %d, %s, %s', [str, num, arr1, arr2])); //111, 222, arr1, arr2

  j.Free;
end;

//遍历
procedure TForm1.Button8Click(Sender: TObject);
var
  j: TJSONObject;
  p: TJSONPair;
  v: TJSONValue;
  i: Integer;
  a: TJSONArray;
begin
  j := TJSONObject.Create;
  j.AddPair('aa', '111');
  j.AddPair('bb', '222');
  j.AddPair('arr', TJSONArray.Create('arr1', 'arr2'));

  //集合遍历 TJSONObject
  for p in j do
    Memo1.Lines.Add(p.ToString); //"aa":"111" \\ "bb":"222" \\ "arr":["arr1","arr2"]

  //索引遍历 TJSONObject, 这里的 Get 函数已不提倡使用了
  for i := 0 to j.Count - 1 do
    Memo1.Lines.Add(j.Get(i).ToString); //"aa":"111" \\ "bb":"222" \\ "arr":["arr1","arr2"]

  //集合遍历 TJSONArray
  for v in j.Values['arr'] as TJSONArray do
    Memo1.Lines.Add(v.Value); //arr1 \\ arr2

  //索引遍历 TJSONArray
  a := j.Values['arr'] as TJSONArray;
  for i := 0 to a.Count - 1 do
    Memo1.Lines.Add(a.Items[i].Value); //arr1 \\ arr2
  j.Free;
end;

//存取到文件
procedure TForm1.Button9Click(Sender: TObject);
var
  j1,j2: TJSONObject;
begin
  //随便虚拟些数据
  j1 := TJSONObject.Create(TJSONPair.Create('aaa', '111'));
  j1.AddPair('bbb', j1.Clone as TJSONValue);

  ChDir('c:\temp');

  //写入文件
  with TStringList.Create do
  begin
    Add(j1.ToString);
    SaveToFile('JsonTest.txt', TEncoding.UTF8); //结果:{"aaa":"111","bbb":{"aaa":"111"}}
    Free;
  end;
  j1.Free;

  //从文件读取
  with TStringList.Create do
  begin
    LoadFromFile('JsonTest.txt', TEncoding.UTF8);
    j2 := TJSONObject.ParseJSONValue(Text) as TJSONObject;
    Free;
  end;

  Memo1.Text := j2.ToString; //结果:{"aaa":"111","bbb":{"aaa":"111"}}
  j2.Free;
end;

//修改、删除
procedure TForm1.Button10Click(Sender: TObject);
var
  j: TJSONObject;
begin
  j := TJSONObject.Create;
  j.AddPair('aaa', '111');
  j.AddPair('bbb', '222');
  j.AddPair('ccc', '333');

  //修改
  j.Get('aaa').JsonValue := TJSONString.Create('11111'); //TJSONPair 的 JsonString、JsonValue 分别是 键、值
//  j.Pairs[0].JsonValue := TJSONString.Create('11111');

  //删除
  j.RemovePair('bbb');

  Memo1.Lines.Add(j.ToString); //结果:{"aaa":"11111","ccc":"333"}

  j.Free;
end;

//根据路径添加数组的函数:
procedure CreateJSONPathArr(aJson: TJSONObject; const aPath: string; jArr: TJSONArray);
var
  arr: TArray<string>;
  path: string;
  i: Integer;
begin
  arr := aPath.Split(['.'], ExcludeEmpty);
  for i := 0 to Length(arr) - 1 do
  begin
    if not aJson.TryGetValue(arr[i], aJson) then
    begin
      if i = Length(arr) - 1 then
        aJson.AddPair(arr[i], jArr)
      else begin
        aJson.AddPair(arr[i], TJSONObject.Create);
        aJson.TryGetValue(arr[i], aJson);
      end;
    end;
  end;
end;

//调用测试:
var
  j: TJSONObject;
  a: TJSONArray;
begin
  j := TJSONObject.Create;

  a := TJSONArray.Create('11', '22');
  CreateJSONPathArr(j, 'aaa.bbb.ccc', a);

  a := TJSONArray.Create('33', '44');
  CreateJSONPathArr(j, 'aaa.bbb.ddd', a);

  j.Free;
end;

jsonDBjsonDB是一个基于JSON格式的内存数据库.它具有以下特点:轻量级. 无守护进程,无需任何额外的安装和配置,你只需要import jsonDb即可使用,非常方便.NOSQL. 类似于mongoDb的非关系型数据库.内存数据库. 所有数据基于内存进行操作和访问,性能相对较高.目前版本的性能测试数据请 参考reference文档.任意迁移. 数据库可以完整导出为外部文件,并且可以从外部文件导入.基于此,数据库可以 进行任意的迁移,而无需做任何修改.灵活的数据类型. 一个数据集合(collection)中的数据,并不需要相同的格式.比如以下几种数据 可以同时存在于一个collection中: {'key1':1},{'key2':'value','pic':'value'},{'key3':'value'}JsonDB使用Python语言实现,是一个github开源项目,遵循MIT的LICENCE,基本上可以不受限制用于任何用途。该DB的接口大体模仿了mongoDB的风格,使用起来非常简单和顺手。概念说明:db: 即数据库. 创建一个jsonDb类的实例,即是创建了一个数据库.可以指定dbname和hash的长度.collection: 数据集合(表). 一个collection可以理解为数据库中的一个表. collection不需要 单独创建,当insert第一条数据,或者ensureKey时,系统会自动创建.data: 数据. collection中的一条数据,或者是一个数据的list. data必须是dict字典类型,是一个 key-value键值对.安装从源码安装,首先从github下载源码,jsonDb源码下载地址python setup.py install功能说明:创建数据库实例化一个JSONDB类实例,即创建一个数据库.我们重载了__str__方法,所以可以通过print直接查看数据库的统计信息.>>> from jsonDb.database import JSONDB >>> myDb = JSONDB('USER_DB') >>> print myDb ------ jdb statics ------ db_name: USER_DB mem_collection: 0 bytes mem_hash: 0 bytes collection_num: 0 **** collection statics ****更多详细使用说明请参考中文说明文档。 标签:jsonDB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值