Delphi中JSon SuperObject 使用:数据集与JSON对象互转

来源:互联网 发布:网络论坛和网络社区 编辑:程序博客网 时间:2024/05/17 09:27

在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;
复制代码
 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 四十天拉今天恶露特别多怎么办 顺产侧切出院几天后伤口裂开怎么办 产后十几撕裂用卫生巾疼怎么办 婴儿绑肚脐的棉黏在肚脐上怎么办 割完双眼皮第五天了很痒怎么办 自体脂肪丰胸做完半年有团块怎么办 假体隆胸一个月了躺着睡很硬怎么办 假体隆胸半月俩胸大小不一样怎么办 假体隆胸拆线后还是起不来床怎么办 假体隆胸术后6天 天天胀痛怎么办 阴部大腿根长了个疙瘩有点痛怎么办 加盟费交了总部不做事怎么办 仓鼠从桌子摔下来后走路别扭怎么办 习惯了一个人天天找你聊天怎么办 来完月经外阴湿疹就严重怎么办 宝宝不肯喝开水尿黄黄的怎么办 做阴超做一半发现忘记换套了怎么办 穿裙子时拉链总往下掉怎么办 子宫内膜厚姨妈来的久怎么办 胸小胸罩往上跑肩带往两边掉怎么办 白衣服弄上姨妈血了洗了变黄怎么办 货物丢失了我感觉没丢这么多怎么办 想穿短裙 但是膝盖怕凉怎么办 被老公看到内裤很脏还有屎怎么办 排卵期同房了不知道怀没怀孕怎么办 清理空调时湿纸巾被卷进去怎么办 超市买的尿不湿质量太差怎么办 把卫生巾和衣服一起洗了怎么办 全面屏面对vo华为手机怎么办屏 雅漾喷雾的喷头坏了怎么办 悦诗风吟水里面有小颗粒怎么办 林肯mkz钥匙锁在车内怎么办 八四消毒液弄到衣服上怎么办 微信朋友圈发过的文章想修改怎么办 白色衣服被洗衣液染色了怎么办 准迁证和迁移证不想迁了怎么办 出了迁移证又想迁到其他地方怎么办 高中的会考如果没g合格怎么办 鞋子里自带的鞋垫坏了怎么办 入厕纸把私处伤了一下怎么办? 夏天做月子用姨妈巾热怎么办