在delphi中,数据集是最常用数据存取方式。因此,必须建立JSON与TDataSet之间的互转关系,实现数据之间通讯与转换。值得注意的是,这只是普通的TDataset与JSON之间转换,由于CDS包含了Delta数据包,其数据格式远比普通的TDataset更复杂。

数据集字段信息,是一个完整的字典信息。因此,我们在JSON必须也建立字典信息,才能创建数据集的字段信息。我们设置其JSON信息如下:

COLS:[字段列表信息],如:

"Cols":[{"JsonType":"integer","FieldIndex":0,"FieldType":"Integer","FieldSize":0,"FieldName":"ID","Required":false},{"JsonType":"string","FieldIndex":1,"FieldType":"String","FieldSize":100,"FieldName":"Title","Required":false},{"JsonType":"variant","FieldIndex":2,"FieldType":"Blob","FieldSize":0,"FieldName":"Picture","Required":false}]

数据信息以Data做节点,也是一个数组嵌套记录信息:

"Data":[记录集信息]

废话少说,直接上代码:

  1. unit uDBJson;
  2. interface
  3. uses
  4. SysUtils,Classes,Variants,DB,DBClient,SuperObject;
  5. type
  6. TTableJSon = class
  7. private
  8. const cstFieldType = 'FieldType';
  9. const cstFieldName = 'FieldName';
  10. const cstFieldSize = 'FieldSize';
  11. const cstJsonType = 'JsonType';
  12. const cstRequired = 'Required';
  13. const cstFieldIndex = 'FieldIndex';
  14. const cstCols= 'Cols';
  15. const cstData= 'Data';
  16. public
  17. class function JSonFromDataSet(DataSet:TDataSet):string;
  18. class function CreateFieldByJson(Fields:TFieldDefs;ColsJson:ISuperObject):Boolean;
  19. class function ImportDataFromJSon(DataSet:TDataSet;DataJson:ISuperObject):Integer;
  20. class function CDSFromJSon(CDS:TClientDataSet;Json:ISuperObject):Boolean;
  21. class function GetValue(Json:ISuperObject;const Name:string):Variant;
  22. class function CreateJsonValue(Json:ISuperObject;const Name:string;const Value:Variant):Boolean;
  23. class function CreateJsonValueByField(Json:ISuperObject;Field:TField):Boolean;
  24. class function GetValue2Field(Field:TField;JsonValue:ISuperObject):Variant;
  25. end;
  26. implementation
  27. uses TypInfo,encddecd;
  28. { TTableJSon }
  29. class function TTableJSon.CDSFromJSon(CDS: TClientDataSet;
  30. Json: ISuperObject): Boolean;
  31. var
  32. ColsJson:ISuperObject;
  33. begin
  34. Result := False;
  35. if Json = nil then
  36. Exit;
  37. CDS.Close;
  38. CDS.Data := Null;
  39. //创建字段
  40. ColsJson := Json.O[cstCols];
  41. CreateFieldByJson(CDS.FieldDefs,ColsJson);
  42. if CDS.FieldDefs.Count >0 then
  43. CDS.CreateDataSet;
  44. ImportDataFromJSon(CDS,Json.O[cstData]);
  45. Result := True;
  46. end;
  47. class function TTableJSon.CreateFieldByJson(Fields: TFieldDefs;
  48. ColsJson: ISuperObject): Boolean;
  49. var
  50. SubJson:ISuperObject;
  51. ft:TFieldType;
  52. begin
  53. Result := False;
  54. Fields.DataSet.Close;
  55. Fields.Clear;
  56. for SubJson in ColsJson do
  57. begin
  58. ft := TFieldType(GetEnumValue(TypeInfo(TFieldType),'ft'+SubJson.S[cstFieldType]));
  59. if ft= ftAutoInc then //自增字段不能录入,必须更改
  60. ft := ftInteger;
  61. Fields.Add(SubJson.S[cstFieldName],ft,SubJson.I[cstFieldSize],SubJson.B[cstRequired]);
  62. end;
  63. Result := True;
  64. end;
  65. class function TTableJSon.CreateJsonValue(Json: ISuperObject;
  66. const Name: string; const Value: Variant): Boolean;
  67. begin
  68. Result := False;
  69. Json.O[Name] := SO(Value);
  70. Result := True;
  71. end;
  72. class function TTableJSon.CreateJsonValueByField(Json: ISuperObject;
  73. Field: TField): Boolean;
  74. begin
  75. Result := False;
  76. if Field Is TDateTimeField then
  77. Json.O[Field.FieldName] := SO(Field.AsDateTime)
  78. else if Field is TBlobField then
  79. Json.S[Field.FieldName] := EncodeString(Field.AsString)
  80. else
  81. Json.O[Field.FieldName] := SO(Field.Value);
  82. Result := True;
  83. end;
  84. class function TTableJSon.GetValue(
  85. Json: ISuperObject;const Name: string): Variant;
  86. begin
  87. case Json.DataType of
  88. stNull: Result := Null;
  89. stBoolean: Result := Json.B[Name];
  90. stDouble: Result := Json.D[Name];
  91. stCurrency: Result := Json.C[Name];
  92. stInt: Result := Json.I[Name];
  93. stString: Result := Json.S[Name];
  94. end;
  95. end;
  96. class function TTableJSon.GetValue2Field(Field: TField; JsonValue:ISuperObject): Variant;
  97. begin
  98. if JsonValue.DataType = stNull then
  99. Result := Null
  100. else if Field is TDateTimeField then
  101. Result := JavaToDelphiDateTime(JsonValue.AsInteger)
  102. else if (Field is TIntegerField) or (Field is TLargeintField) then
  103. Result := JsonValue.AsInteger
  104. else if Field is TNumericField then
  105. Result := JsonValue.AsDouble
  106. else if Field is TBooleanField then
  107. Result := JsonValue.AsBoolean
  108. else if Field is TStringField then
  109. Result := JsonValue.AsString
  110. else if Field is TBlobField then
  111. Result := DecodeString(JsonValue.AsString)
  112. end;
  113. class function TTableJSon.ImportDataFromJSon(DataSet: TDataSet;
  114. DataJson: ISuperObject): Integer;
  115. var
  116. SubJson:ISuperObject;
  117. i:Integer;
  118. iter: TSuperObjectIter;
  119. begin
  120. if not DataSet.Active then
  121. DataSet.Open;
  122. DataSet.DisableControls;
  123. try
  124. for SubJson in DataJson do
  125. begin
  126. DataSet.Append;
  127. if ObjectFindFirst(SubJson,iter) then
  128. begin
  129. repeat
  130. if DataSet.FindField(iter.Ite.Current.Name)<>nil then
  131. DataSet.FindField(iter.Ite.Current.Name).Value :=
  132. GetValue2Field(
  133. DataSet.FindField(iter.Ite.Current.Name),
  134. iter.Ite.Current.Value);
  135. until not ObjectFindNext(iter) ;
  136. end;
  137. DataSet.Post;
  138. end;
  139. finally
  140. DataSet.EnableControls;
  141. end;
  142. end;
  143. class function TTableJSon.JSonFromDataSet(DataSet:TDataSet):string;
  144. procedure GetFieldTypeInfo(Field:TField;var Fieldtyp,JsonTyp:string);
  145. begin
  146. Fieldtyp := GetEnumName(TypeInfo(tfieldtype),ord(Field.DataType));
  147. Delete(Fieldtyp,1,2);
  148. if Field is TStringField then
  149. JsonTyp := 'string'
  150. else if Field is TDateTimeField then
  151. JsonTyp := 'integer'
  152. else if (Field is TIntegerField) or (Field is TLargeintField) then
  153. JsonTyp := 'integer'
  154. else if Field is TCurrencyField then
  155. JsonTyp := 'currency'
  156. else if Field is TNumericField then
  157. JsonTyp := 'double'
  158. else if Field is TBooleanField then
  159. JsonTyp := 'boolean'
  160. else
  161. JsonTyp := 'variant';
  162. end;
  163. var
  164. sj,aj,sj2:ISuperObject;
  165. i:Integer;
  166. Fieldtyp,JsonTyp:string;
  167. List:TStringList;
  168. begin
  169. sj := SO();
  170. //创建列
  171. aj := SA([]);
  172. List := TStringList.Create;
  173. try
  174. List.Sorted := True;
  175. for i := 0 to DataSet.FieldCount - 1 do
  176. begin
  177. sj2 := SO();
  178. GetFieldTypeInfo(DataSet.Fields[i],Fieldtyp,JsonTyp);
  179. sj2.S[cstFieldName] := DataSet.Fields[i].FieldName;
  180. sj2.S[cstFieldType] := Fieldtyp;
  181. sj2.S[cstJsonType] := JsonTyp;
  182. sj2.I[cstFieldSize] := DataSet.Fields[i].Size;
  183. sj2.B[cstRequired] := DataSet.Fields[i].Required;
  184. sj2.I[cstFieldIndex] := DataSet.Fields[i].Index;
  185. aj.AsArray.Add(sj2);
  186. List.Add(DataSet.Fields[i].FieldName+'='+JsonTyp);
  187. end;
  188. sj.O['Cols'] := aj;
  189. //创建数据集的数据
  190. DataSet.DisableControls;
  191. DataSet.First;
  192. aj := SA([]);
  193. while not DataSet.Eof do
  194. begin
  195. sj2 := SO();
  196. for i := 0 to DataSet.FieldCount - 1 do
  197. begin
  198. //sj2.S[IntToStr(DataSet.Fields[i].Index)] := VarToStrDef(DataSet.Fields[i].Value,'');
  199. if VarIsNull(DataSet.Fields[i].Value) then
  200. sj2.O[DataSet.Fields[i].FieldName] := SO(Null)
  201. else
  202. begin
  203. CreateJsonValueByField(sj2,DataSet.Fields[i]);
  204. end;
  205. end;
  206. aj.AsArray.Add(sj2);
  207. DataSet.Next;
  208. end;
  209. sj.O['Data'] := aj;
  210. Result := sj.AsString;
  211. finally
  212. List.Free;
  213. DataSet.EnableControls;
  214. end;
  215. end;
  216. end.
  217. 调用示例:
  218. //数据集转JSON对象或JSON文本
  219. var
  220. json:TTableJSon;
  221. s:string;
  222. begin
  223. S := json.JSonFromDataSet(ADODataSet1);
  224. //在用TStringStream读入字符串S,存成文本,看看其格式.
  225. end;
  226. //JSON对象或文本,装载到数据集
  227. var
  228. json:ISuperObject;
  229. begin
  230. json := TSuperObject.ParseFile('json.txt',False);
  231. TTableJSon.CDSFromJSon(cdsJSON,json);
  232. end;
http://blog.csdn.net/diligentcatrich/article/details/6913512

delphi json(CDS包含了Delta数据包)的更多相关文章

  1. IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习

    相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...

  2. c# 生成json数据包

    json数据类型,归根到底就是一个字符串,管他里面什么格式,它就是一个字符串来的! 看一个json数据包: { "touser":"OPENID", " ...

  3. Asp.Net Core 轻松学-实现跨平台的自定义Json数据包

    前言     在前后端分离的业务开发中,我们总是需要返回各种各样的数据包格式,一个良好的 json 格式数据包是我们一贯奉行的原则,下面就利用 Json.Net 来做一个简单具有跨平台的序列化数据包实 ...

  4. 使用Ajax方式POST JSON数据包(转)

    add by zhj: 用ajax发送json数据时注意两点, 第一,使用JSON.stringify()函数将data转为json格式的字符串,如下 data: JSON.stringify({   ...

  5. 前端学习——使用Ajax方式POST JSON数据包

    0.前言     本文解释怎样使用Jquery中的ajax方法传递JSON数据包,传递的方法使用POST(当然PUT又有时也是一个不错的选择).POST JSON数据包相比标准的POST格式可读性更好 ...

  6. Fiddler 抓取手机APP数据包

    Fiddler是一个调试代理,下载地址http://www.telerik.com/download/fiddler 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接 ...

  7. 利用Fiddler抓取手机APP数据包

    Fiddler是一个调试代理,下载地址http://www.telerik.com/download/fiddler 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接 ...

  8. Wireshark数据抓包教程之认识捕获分析数据包

    Wireshark数据抓包教程之认识捕获分析数据包 认识Wireshark捕获数据包 当我们对Wireshark主窗口各部分作用了解了,学会捕获数据了,接下来就该去认识这些捕获的数据包了.Wiresh ...

  9. Fiddler2 抓取手机APP数据包

    原文:http://blog.goyiyo.com/archives/2044 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接设置里的高级里,代理设置填写上Fidd ...

随机推荐

  1. android取得所在位置的经纬度

    android提供了LocationManager来取得位置,用LocationListener来监听位置的变化 先做一些初始化工作: /** latitude and longitude of cu ...

  2. python读取EXCLE文件数据

    python读取EXCEL,利用 Google 搜索 Python Excel,点击第一条结果http://www.python-excel.org/ ,能够跨平台处理 Excel. 按照文档一步步去 ...

  3. bresenham算法的FPGA的实现1

    接着上一篇的 计算实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点.http://www.cnblogs.com/sepeng/p/4042464.html 这种直接算法的确是被鄙视了 强大 ...

  4. Python 2.7 学习笔记 访问mysql数据库

    一.基本概念 使用python操作数据库,其基本的流程如下(其实所有开发语言访问数据库的流程都是这样). 1.第一,引入相应数据库的python数据库接口模块,针对不同的数据库类型,有不同的数据库访问 ...

  5. 设计模式(七)组合模式Composite(结构型)

    设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...

  6. H面试程序(28):字符串处理转换

    //2 字符串处理转换 //问题描述: //在给定字符串中找出单词( “单词”由大写字母和小写字母字符构成, //其他非字母字符视为单词的间隔,如空格.问号.数字等等:另外单个字母不算单词): //找 ...

  7. Codeforces 437C The Child and Toy(贪心)

    题目连接:Codeforces 437C  The Child and Toy 贪心,每条绳子都是须要割断的,那就先割断最大值相应的那部分周围的绳子. #include <iostream> ...

  8. 无法启动outlook mapi

    office2013 管理员权限,在命令行中定位到office15文件夹,然后运行命令"outlook /importprf ..prf"

  9. 为什么我的outlook只能收信不能发信,发送测试电子邮件消息: 无法发送此邮件。请在帐户属性中验证电子邮件

    链接地址:http://zhidao.baidu.com/link?url=aVIFo2aNLuHIZGZuEUataHkZp4XApHqyvbEK8ACHPhi3jwhGhM0GBAtm72AnsP ...

  10. servlet 将输入内容通过拼接页面的方式显示出来

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...