JsonDataObjects序列和还原
JsonDataObjects号称DELPHI最快的JSON库,且支持跨平台。
// cxg 2017-9-12
// Use JsonDataObjects(cross platform json library)
// Use delphi 10.2.1
unit ujson;
interface
uses
?System.SysUtils, soap.EncdDecd, Web.HTTPApp, System.NetEncoding, Data.DB,
?System.Classes, JsonDataObjects;
// {"data":[{"field1":value1,"field2":value2}]};
function datasetToJson(dataset: TDataSet): string;
// {"data":[{"field1":value1,"field2":value2}]};
procedure jsonToDataset(const json: string; dataset: TDataSet);
// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};
function datasetToJsonCols(dataset: TDataSet): string;
// {
// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]
// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]
// ,"delete":[{"table":"表1","where":"字段1=1"}]
// };
procedure parseJsonSql(const json: string; outsql: TStrings);
implementation
procedure parseJsonSql(const json: string; outsql: TStrings);
// {
// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]
// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]
// ,"delete":[{"table":"表1","where":"字段1=1"}]
// };
var
?obj, childobj: TJsonObject;
?tablename, sql, lname, lvalue, where: string;
?i, j: Integer;
?function _getValue(value: PJsonDataValue): string;
?{
?TJsonDataType = (
?jdtNone, jdtString, jdtInt, jdtLong, jdtULong, jdtFloat, jdtDateTime
?, jdtBool, jdtArray, jdtObject
?);
?}
?begin
???case Value.Typ of
?????jdtString: Result := QuotedStr(UTF8ToString(rawbytestring(TNetEncoding.URL.Decode(value.Value)))); ?// 解码
?????jdtBool: Result := BoolToStr(value.BoolValue);
?????jdtFloat: Result := FloatToStr(value.FloatValue);
?????jdtInt, jdtLong, jdtULong: Result := IntToStr(value.IntValue);
?????jdtDateTime: Result := DateTimeToStr(value.DateTimeValue);
???end;
?end;
begin
?if outsql = nil then
???Exit;
?outsql.Clear;
?obj := TJsonObject.Parse(json) as TJsonObject;
?try
???// 解析并生成insert sql begin-----------------------------------
???for i := 0 to obj.A[‘insert‘].Count - 1 do
???begin
?????childobj := obj.A[‘insert‘].O[i];
?????lname := ‘‘;
?????lvalue := ‘‘;
?????for j := 0 to childobj.Count - 1 do
?????begin
???????if childobj.Names[j] = ‘table‘ then
???????begin
?????????tablename := childobj.Items[j].Value;
?????????Continue;
???????end;
???????if lname = ‘‘ then
?????????lname := childobj.Names[j]
???????else
?????????lname := lname + ‘,‘ + childobj.Names[j];
???????if lvalue = ‘‘ then
?????????lvalue := _getValue(childobj.Items[j])
???????else
?????????lvalue := lvalue + ‘,‘ + _getValue(childobj.Items[j]);
?????end;
?????sql := ‘insert into ‘ + tablename + ‘ (‘ + lname + ‘) values (‘ + lvalue + ‘)‘;
?????outsql.Add(sql);
???end;
???// 解析并生成insert sql end----------------------------------------
???// 解析并生成update sql begin---------------------------------------
???for i := 0 to obj.A[‘update‘].Count - 1 do
???begin
?????childobj := obj.A[‘update‘].O[i];
?????lname := ‘‘;
?????lvalue := ‘‘;
?????for j := 0 to childobj.Count - 1 do
?????begin
???????if childobj.Names[j] = ‘table‘ then
???????begin
?????????tablename := childobj.Items[j].Value;
?????????Continue;
???????end
???????else
???????if childobj.Names[j] = ‘where‘ then
???????begin
?????????where := childobj.Items[j].Value;
?????????Continue;
???????end;
???????if lname = ‘‘ then
?????????lname := childobj.Names[j] + ‘=‘ + _getValue(childobj.Items[j])
???????else
?????????lname := lname + ‘,‘ + childobj.Names[j] + ‘=‘ + _getValue(childobj.Items[j]);
?????end;
?????sql := ‘update ‘ + tablename + ‘ set ‘ + lname + ‘ where ‘ + where;
?????outsql.Add(sql);
???end;
???// 解析并生成update sql end--------------------------------------------
???// 解析并生成delete sql begin--------------------------------------------
???for i := 0 to obj.A[‘delete‘].Count - 1 do
???begin
?????childobj := obj.A[‘delete‘].O[i];
?????lname := ‘‘;
?????lvalue := ‘‘;
?????for j := 0 to childobj.Count - 1 do
?????begin
???????if childobj.Names[j] = ‘table‘ then
???????begin
?????????tablename := childobj.Items[j].Value;
?????????Continue;
???????end
???????else
???????if childobj.Names[j] = ‘where‘ then
???????begin
?????????where := childobj.Items[j].Value;
?????????Continue;
???????end;
?????end;
?????sql := ‘delete from ‘ + tablename + ‘ where ‘ + where;
?????outsql.Add(sql);
???end;
???// 解析并生成delete sql end-------------------------------------------
?finally
???obj.free;
?end;
end;
function datasetToJsonCols(dataset: TDataSet): string;
// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};
var
?i: Integer;
?obj, childobj: TJsonObject;
?field: TField;
?blob: TStringStream;
?function _getFieldType(fld: TField): string;
?begin
???case fld.DataType of
?????ftBoolean:
???????Result := ‘bool‘;
?????ftSmallint, ftInteger, ftWord, ftAutoInc:
???????Result := ‘int‘;
?????ftLargeint:
???????Result := ‘int64‘;
?????ftFloat, ftBCD, ftCurrency:
???????Result := ‘float‘;
?????ftTimeStamp, ftDate, ftTime, ftDateTime:
???????Result := ‘datetime‘;
?????ftString, ftFixedChar, ftMemo, ftWideString:
???????Result := ‘string‘;
?????ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
???????Result := ‘blob‘;
???end;
?end;
begin
?// {"cols":[{"name":"c1","size":0,"type":"int"}]"data":[{"c1":1}]};
?Result := ‘{"result":"false"}‘;
?if (dataset = nil) or (not dataset.Active) then
???Exit;
?obj := TJsonObject.Create;
?obj.A[‘cols‘];
?obj.A[‘data‘];
?dataset.First;
?for i := 0 to dataset.FieldCount - 1 do ??// fill cols array
?begin
???field := dataset.Fields[i];
???childobj := obj.A[‘cols‘].AddObject;
???childobj.S[‘name‘] := field.FieldName;
???childobj.I[‘size‘] := field.Size;
???childobj.S[‘type‘] := _getFieldType(field);
???childobj.B[‘required‘] := field.Required;
???childobj.B[‘readonly‘] := field.ReadOnly;
?end;
?// fill data array
?dataset.First;
?while not dataset.Eof do
?begin
???childobj := obj.A[‘data‘].AddObject;
???for i := 0 to dataset.FieldCount - 1 do
???begin
?????field := dataset.Fields[i];
?????if field.IsNull then
???????childobj.S[field.FieldName] := ‘‘
?????else
?????begin
???????case field.DataType of
?????????ftBoolean:
???????????childobj.B[field.FieldName] := field.AsBoolean;
?????????ftSmallint, ftInteger, ftWord, ftAutoInc:
???????????childobj.I[field.FieldName] := field.AsInteger;
?????????ftLargeint:
???????????childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;
?????????ftFloat, ftBCD, ftCurrency:
???????????childobj.F[field.FieldName] := field.AsFloat;
?????????ftTimeStamp, ftDate, ftTime, ftDateTime:
???????????childobj.D[field.FieldName] := field.AsDateTime;
?????????ftString, ftFixedChar, ftMemo, ftWideString:
???????????childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString))); ?????// 编码
?????????ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
???????????begin
?????????????blob := TStringStream.Create(‘‘);
?????????????try
???????????????TBlobField(field).SaveToStream(blob);
???????????????childobj.S[field.FieldName] := EncodeString(blob.DataString); ?// base64 编码
?????????????finally
???????????????blob.Free;
?????????????end;
???????????end;
???????end;
?????end;
???end; ???// end for
???dataset.Next;
?end; ????// end while
?Result := obj.ToString;
end;
procedure jsonToDataset(const json: string; dataset: TDataSet);
// {"data":[{"field1":value1,"field2":value2}]};
var
?obj, childobj: TJsonObject;
?i, j: Integer;
?field: TField;
?blob: TStringStream;
begin
?if (dataset = nil) or (not dataset.Active) or (json = ‘{"result":"false"}‘) then
???Exit;
?obj := TJsonObject.Parse(json) as TJsonObject;
?dataset.DisableControls;
?try
???for i := 0 to obj.A[‘data‘].Count - 1 do
???begin
?????dataset.Append;
?????childobj := obj.A[‘data‘].O[i];
?????if childobj = nil then
???????continue;
?????for j := 0 to dataset.FieldCount - 1 do
?????begin
???????field := dataset.Fields[j];
???????if field = nil then
?????????Continue;
???????case field.datatype of
?????????ftBoolean:
???????????field.AsBoolean := childobj.B[field.FieldName];
?????????ftFloat, ftBCD, ftCurrency:
???????????field.AsFloat := childobj.F[field.FieldName];
?????????ftSmallint, ftInteger, ftWord, ftAutoInc:
???????????field.AsInteger := childobj.I[field.FieldName];
?????????ftString, ftFixedChar, ftMemo, ftWideString:
???????????field.AsString :=UTF8ToString(rawbytestring( TNetEncoding.URL.Decode(childobj.S[field.FieldName]))); ?// 解码
?????????ftTimeStamp, ftDate, ftTime, ftDateTime:
???????????field.AsDateTime := childobj.D[field.FieldName];
?????????ftLargeint:
???????????TLargeintField(field).AsLargeInt := childobj.L[field.FieldName];
?????????ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
???????????begin
?????????????blob := TStringStream.Create(DecodeString(childobj.S[field.FieldName]));
?????????????try
???????????????TBlobField(field).LoadFromStream(blob);
?????????????finally
???????????????blob.Free;
?????????????end;
???????????end;
???????end;
?????end;
?????dataset.Post;
???end;
?finally
???dataset.EnableControls;
???obj.free;
?end;
end;
function datasetToJson(dataset: TDataSet): string;
// {"data":[{"field1":value1,"field2":value2}]};
var
?i: Integer;
?obj, childobj: TJsonObject;
?field: TField;
?blob: TStringStream;
begin
?Result := ‘{"result":"false"}‘;
?if (dataset = nil) or (not dataset.Active) then
???Exit;
?obj := TJsonObject.Create;
?try
???obj.A[‘data‘];
???dataset.First;
???while not dataset.Eof do
???begin
?????childobj := obj.A[‘data‘].AddObject;
?????for i := 0 to dataset.FieldCount - 1 do
?????begin
???????field := dataset.Fields[i];
???????if field.IsNull then
?????????childobj.S[field.FieldName] := ‘‘
???????else
???????begin
?????????case field.datatype of
???????????ftBoolean:
?????????????childobj.B[field.FieldName] := field.AsBoolean;
???????????ftSmallint, ftInteger, ftWord, ftAutoInc:
?????????????childobj.I[field.FieldName] := field.AsInteger;
???????????ftLargeint:
?????????????childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;
???????????ftCurrency, ftFloat, ftBCD:
?????????????childobj.F[field.FieldName] := field.AsFloat;
???????????ftTimeStamp, ftDate, ftTime, ftDateTime:
?????????????childobj.D[field.FieldName] := field.AsDateTime;
???????????ftString, ftFixedChar, ftMemo, ftWideString:
?????????????childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString)));
???????????ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
?????????????begin
???????????????blob := TStringStream.Create(‘‘);
???????????????try
?????????????????TBlobField(field).SaveToStream(blob);
?????????????????childobj.S[field.FieldName] := EncodeString(blob.DataString); ?// base64 编码
???????????????finally
?????????????????blob.Free;
???????????????end;
?????????????end;
?????????end;
???????end;
?????end; ???// end for
?????dataset.Next;
???end; ??// end while
???Result := obj.ToString;
?finally
???obj.Free;
?end;
end;
end.
JsonDataObjects序列和还原
原文地址:http://www.cnblogs.com/hnxxcxg/p/7513933.html