delphi json(CDS包含了Delta数据包)
在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":[记录集信息]
废话少说,直接上代码:
- unit uDBJson;
- interface
- uses
- SysUtils,Classes,Variants,DB,DBClient,SuperObject;
- type
- TTableJSon = class
- private
- const cstFieldType = 'FieldType';
- const cstFieldName = 'FieldName';
- const cstFieldSize = 'FieldSize';
- const cstJsonType = 'JsonType';
- const cstRequired = 'Required';
- const cstFieldIndex = 'FieldIndex';
- const cstCols= 'Cols';
- const cstData= 'Data';
- public
- class function JSonFromDataSet(DataSet:TDataSet):string;
- class function CreateFieldByJson(Fields:TFieldDefs;ColsJson:ISuperObject):Boolean;
- class function ImportDataFromJSon(DataSet:TDataSet;DataJson:ISuperObject):Integer;
- class function CDSFromJSon(CDS:TClientDataSet;Json:ISuperObject):Boolean;
- class function GetValue(Json:ISuperObject;const Name:string):Variant;
- class function CreateJsonValue(Json:ISuperObject;const Name:string;const Value:Variant):Boolean;
- class function CreateJsonValueByField(Json:ISuperObject;Field:TField):Boolean;
- class function GetValue2Field(Field:TField;JsonValue:ISuperObject):Variant;
- end;
- implementation
- uses TypInfo,encddecd;
- { TTableJSon }
- class function TTableJSon.CDSFromJSon(CDS: TClientDataSet;
- Json: ISuperObject): Boolean;
- var
- ColsJson:ISuperObject;
- begin
- Result := False;
- if Json = nil then
- Exit;
- CDS.Close;
- CDS.Data := Null;
- //创建字段
- ColsJson := Json.O[cstCols];
- CreateFieldByJson(CDS.FieldDefs,ColsJson);
- if CDS.FieldDefs.Count >0 then
- CDS.CreateDataSet;
- ImportDataFromJSon(CDS,Json.O[cstData]);
- Result := True;
- end;
- class function TTableJSon.CreateFieldByJson(Fields: TFieldDefs;
- ColsJson: ISuperObject): Boolean;
- var
- SubJson:ISuperObject;
- ft:TFieldType;
- begin
- Result := False;
- Fields.DataSet.Close;
- Fields.Clear;
- for SubJson in ColsJson do
- begin
- ft := TFieldType(GetEnumValue(TypeInfo(TFieldType),'ft'+SubJson.S[cstFieldType]));
- if ft= ftAutoInc then //自增字段不能录入,必须更改
- ft := ftInteger;
- Fields.Add(SubJson.S[cstFieldName],ft,SubJson.I[cstFieldSize],SubJson.B[cstRequired]);
- end;
- Result := True;
- end;
- class function TTableJSon.CreateJsonValue(Json: ISuperObject;
- const Name: string; const Value: Variant): Boolean;
- begin
- Result := False;
- Json.O[Name] := SO(Value);
- Result := True;
- end;
- class function TTableJSon.CreateJsonValueByField(Json: ISuperObject;
- Field: TField): Boolean;
- begin
- Result := False;
- if Field Is TDateTimeField then
- Json.O[Field.FieldName] := SO(Field.AsDateTime)
- else if Field is TBlobField then
- Json.S[Field.FieldName] := EncodeString(Field.AsString)
- else
- Json.O[Field.FieldName] := SO(Field.Value);
- Result := True;
- end;
- class function TTableJSon.GetValue(
- Json: ISuperObject;const Name: string): Variant;
- begin
- case Json.DataType of
- stNull: Result := Null;
- stBoolean: Result := Json.B[Name];
- stDouble: Result := Json.D[Name];
- stCurrency: Result := Json.C[Name];
- stInt: Result := Json.I[Name];
- stString: Result := Json.S[Name];
- end;
- end;
- class function TTableJSon.GetValue2Field(Field: TField; JsonValue:ISuperObject): Variant;
- begin
- if JsonValue.DataType = stNull then
- Result := Null
- else if Field is TDateTimeField then
- Result := JavaToDelphiDateTime(JsonValue.AsInteger)
- else if (Field is TIntegerField) or (Field is TLargeintField) then
- Result := JsonValue.AsInteger
- else if Field is TNumericField then
- Result := JsonValue.AsDouble
- else if Field is TBooleanField then
- Result := JsonValue.AsBoolean
- else if Field is TStringField then
- Result := JsonValue.AsString
- else if Field is TBlobField then
- Result := DecodeString(JsonValue.AsString)
- end;
- class function TTableJSon.ImportDataFromJSon(DataSet: TDataSet;
- DataJson: ISuperObject): Integer;
- var
- SubJson:ISuperObject;
- i:Integer;
- iter: TSuperObjectIter;
- begin
- if not DataSet.Active then
- DataSet.Open;
- DataSet.DisableControls;
- try
- for SubJson in DataJson do
- begin
- DataSet.Append;
- if ObjectFindFirst(SubJson,iter) then
- begin
- repeat
- if DataSet.FindField(iter.Ite.Current.Name)<>nil then
- DataSet.FindField(iter.Ite.Current.Name).Value :=
- GetValue2Field(
- DataSet.FindField(iter.Ite.Current.Name),
- iter.Ite.Current.Value);
- until not ObjectFindNext(iter) ;
- end;
- DataSet.Post;
- end;
- finally
- DataSet.EnableControls;
- end;
- end;
- class function TTableJSon.JSonFromDataSet(DataSet:TDataSet):string;
- procedure GetFieldTypeInfo(Field:TField;var Fieldtyp,JsonTyp:string);
- begin
- Fieldtyp := GetEnumName(TypeInfo(tfieldtype),ord(Field.DataType));
- Delete(Fieldtyp,1,2);
- if Field is TStringField then
- JsonTyp := 'string'
- else if Field is TDateTimeField then
- JsonTyp := 'integer'
- else if (Field is TIntegerField) or (Field is TLargeintField) then
- JsonTyp := 'integer'
- else if Field is TCurrencyField then
- JsonTyp := 'currency'
- else if Field is TNumericField then
- JsonTyp := 'double'
- else if Field is TBooleanField then
- JsonTyp := 'boolean'
- else
- JsonTyp := 'variant';
- end;
- var
- sj,aj,sj2:ISuperObject;
- i:Integer;
- Fieldtyp,JsonTyp:string;
- List:TStringList;
- begin
- sj := SO();
- //创建列
- aj := SA([]);
- List := TStringList.Create;
- try
- List.Sorted := True;
- for i := 0 to DataSet.FieldCount - 1 do
- begin
- sj2 := SO();
- GetFieldTypeInfo(DataSet.Fields[i],Fieldtyp,JsonTyp);
- sj2.S[cstFieldName] := DataSet.Fields[i].FieldName;
- sj2.S[cstFieldType] := Fieldtyp;
- sj2.S[cstJsonType] := JsonTyp;
- sj2.I[cstFieldSize] := DataSet.Fields[i].Size;
- sj2.B[cstRequired] := DataSet.Fields[i].Required;
- sj2.I[cstFieldIndex] := DataSet.Fields[i].Index;
- aj.AsArray.Add(sj2);
- List.Add(DataSet.Fields[i].FieldName+'='+JsonTyp);
- end;
- sj.O['Cols'] := aj;
- //创建数据集的数据
- DataSet.DisableControls;
- DataSet.First;
- aj := SA([]);
- while not DataSet.Eof do
- begin
- sj2 := SO();
- for i := 0 to DataSet.FieldCount - 1 do
- begin
- //sj2.S[IntToStr(DataSet.Fields[i].Index)] := VarToStrDef(DataSet.Fields[i].Value,'');
- if VarIsNull(DataSet.Fields[i].Value) then
- sj2.O[DataSet.Fields[i].FieldName] := SO(Null)
- else
- begin
- CreateJsonValueByField(sj2,DataSet.Fields[i]);
- end;
- end;
- aj.AsArray.Add(sj2);
- DataSet.Next;
- end;
- sj.O['Data'] := aj;
- Result := sj.AsString;
- finally
- List.Free;
- DataSet.EnableControls;
- end;
- end;
- end.
- 调用示例:
- //数据集转JSON对象或JSON文本
- var
- json:TTableJSon;
- s:string;
- begin
- S := json.JSonFromDataSet(ADODataSet1);
- //在用TStringStream读入字符串S,存成文本,看看其格式.
- end;
- //JSON对象或文本,装载到数据集
- var
- json:ISuperObject;
- begin
- json := TSuperObject.ParseFile('json.txt',False);
- TTableJSon.CDSFromJSon(cdsJSON,json);
- end;
delphi json(CDS包含了Delta数据包)的更多相关文章
- IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习
相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...
- c# 生成json数据包
json数据类型,归根到底就是一个字符串,管他里面什么格式,它就是一个字符串来的! 看一个json数据包: { "touser":"OPENID", " ...
- Asp.Net Core 轻松学-实现跨平台的自定义Json数据包
前言 在前后端分离的业务开发中,我们总是需要返回各种各样的数据包格式,一个良好的 json 格式数据包是我们一贯奉行的原则,下面就利用 Json.Net 来做一个简单具有跨平台的序列化数据包实 ...
- 使用Ajax方式POST JSON数据包(转)
add by zhj: 用ajax发送json数据时注意两点, 第一,使用JSON.stringify()函数将data转为json格式的字符串,如下 data: JSON.stringify({ ...
- 前端学习——使用Ajax方式POST JSON数据包
0.前言 本文解释怎样使用Jquery中的ajax方法传递JSON数据包,传递的方法使用POST(当然PUT又有时也是一个不错的选择).POST JSON数据包相比标准的POST格式可读性更好 ...
- Fiddler 抓取手机APP数据包
Fiddler是一个调试代理,下载地址http://www.telerik.com/download/fiddler 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接 ...
- 利用Fiddler抓取手机APP数据包
Fiddler是一个调试代理,下载地址http://www.telerik.com/download/fiddler 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接 ...
- Wireshark数据抓包教程之认识捕获分析数据包
Wireshark数据抓包教程之认识捕获分析数据包 认识Wireshark捕获数据包 当我们对Wireshark主窗口各部分作用了解了,学会捕获数据了,接下来就该去认识这些捕获的数据包了.Wiresh ...
- Fiddler2 抓取手机APP数据包
原文:http://blog.goyiyo.com/archives/2044 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接设置里的高级里,代理设置填写上Fidd ...
随机推荐
- Linux 各类软件整理汇总
关于前端和后端的解释 详细链接见:http://wiki.ubuntu.org.cn/Qref/Apps Linux下程序通常不需要作为一个整体,而是模块化,于是有了可选的前端和后端——这种情况下:前 ...
- Java怎样高速构造JSON字符串
目标:依据key/value高速构造一个JSON字符串作为參数提交到web REST API服务上. 分别測试里阿里巴巴的FastJson和Google Gson,终于我採用了Google Gson来 ...
- 关于int.TryParse的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- BZOJ 3713: [PA2014]Iloczyn( 枚举 )
斐波那契数列<10^9的数很少很少...所以直接暴力枚举就行了... ------------------------------------------------------------- ...
- 安装帝国CMS遇到“修改php.ini,将:short_open_tag 设为 On”的解决方法+“建立目录不成功!请检查目录权限”问题
想用安装个帝国CMS来做个网站,于是下载了程序,上传到服务器上,但是在输入安装路径的时候却给出了如下图示: 您的PHP配置文件php.ini配置有问题,请按下面操作即可解决: 1.修改php.ini, ...
- Appium 服务命令行参数
Appium 可以直接通过命令行启动,同样支持命令行参数配置 参考: http://appium.io/slate/cn/master/ 使用方法 例如: appium --shell 服务器标志 ...
- POJ 1458 最长公共子序列 LCS
经典的最长公共子序列问题. 状态转移方程为 : if(x[i] == Y[j]) dp[i, j] = dp[i - 1, j - 1] +1 else dp[i, j] = max(dp[i - 1 ...
- 基于visual Studio2013解决算法导论之045斐波那契堆
题目 斐波那契堆 解决代码及点评 // 斐波那契堆.cpp : 定义控制台应用程序的入口点. // #include<iostream> #include<cstdio> ...
- 关于apche无缘无故个启动不了,解决方法
1. 对于用户不小心把apache下的conf文件不小心给修改了,可那会导致,启动不了apache, 解决办法可以重新下载一个, 64为 32位 下载地址 http://www.veryhuo.c ...
- bzoj 1901: Zju2112 Dynamic Rankings(树套树)
1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...