zoukankan      html  css  js  c++  java
  • Delphi中JSon SuperObject 使用:数据集与JSON对象互转

    在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; 

    http://blog.csdn.net/diligentcatrich/article/details/6916288

  • 相关阅读:
    ios布局约束
    IOSanimationDidStop
    iosanimationWithKeyPath
    CALayer的分析
    关于集合的小demo
    关于集合越界后 不能使用迭代器遍历的处理方式
    html--day02
    关于LIst Set Map 异常的知识点---我的笔记
    css入门
    html相关标记的含义
  • 原文地址:https://www.cnblogs.com/findumars/p/5218039.html
Copyright © 2011-2022 走看看