【问题标题】:How to store blob to database thru Datasnap REST server?如何通过 Datasnap REST 服务器将 blob 存储到数据库?
【发布时间】:2017-01-16 17:30:35
【问题描述】:

前言:

我们使用 Firemonkey 应用程序,然后与 DataSnap REST 服务器交互。此服务器使用 SQLite 数据库。在客户端,我们使用 FireDac Memtable 来管理数据。通常为了更新数据,我们编辑 FDMemTable,然后我们使用一个名为 ApplyUpdate 的函数(简而言之)创建一个 TFDJSONDeltas,然后将其传递给服务器以应用更新。这适用于所有“标准”数据类型。

现在我们必须在数据库中存储一个blob,它是企业的标志。

一些调查:

我们发现了一些使用 FDQuery 的 PARAMS 和 EXECUTE 函数的示例,但我们在客户端没有 FDQuery。许多示例是针对 FDQuery 的,我们没有看到针对 FDMemTable 的示例。 FDMemtable 没有 ExecSQL 功能。

我们还看到了许多带有 TBlobStream 的算法,(但除非我们错过了正确的单元声明),这个对象似乎没有在 Firemonkey 端实现。

问题:

有一种方法可以使用 FDMemTable 执行此任务,还是先将图像上传到服务器然后让服务器执行将图像添加到 blob 字段的任务更好?

【问题讨论】:

    标签: rest delphi blob firedac firemonkey-fm3


    【解决方案1】:

    我可以通过以下方式将 blob 字段发送到 DataSnap REST 服务器:

    客户端:

    var
       mes: TMemoryStream;
       FDMemUp: TFDMemTable;
       LDeltaList: TFDJSONDeltas;
      begin
       mes:= TMemoryStream.Create;
    
       FDMemUp:= TFDMemTable.Create(nil);
       FDMemUp.CachedUpdates:= true;
       FDMemUp.FieldDefs.Add('IMAGE',ftBlob);
       FDMemUp.FieldDefs.Add('ID',ftInteger);
       FDMemUp.CreateDataSet;
    
       //append one record with blob field filled from stream
       FDMemUp.Append;
       (FDMemUp.FieldByName('ID') as TIntegerField).AsInteger:= 106;
       (FDMemUp.FieldByName('IMAGE') as TBlobField).LoadFromStream(mes);
       FDMemUp.Post;
    
       //send dataset to server 
       try
        try
          LDeltaList:= TFDJSONDeltas.Create;
          TFDJSONDeltasWriter.ListAdd(LDeltaList, 'INFOLOGO', FDMemUp);
          Result:= DM.ServerCoreClient.SendData(LDeltaList);
        except
          Result:= nil;
        end;
       finally
        FreeAndNil(FDMemUp);
        FreeAndNil(mes);
       end;
    

    然后在服务器端处理数据:

    function TDMCore.SendData(const ADeltaList: TFDJSONDeltas): boolean;
    var
     LApply: IFDJSONDeltasApplyUpdates;
     mes: TMemoryStream;
    begin
     LApply:= TFDJSONDeltasApplyUpdates.Create(ADeltaList);
     if (LApply.Values[0].RecordCount > 0) then
      begin
       mes:= TMemoryStream.Create;
       LApply.Values[0].First;
       while not LApply.Values[0].Eof do
        begin
         mes.Clear;
         //read stream data from blob field
         (LApply.Values[0].Fields[1] as TBlobField).SaveToStream(mes);
         mes.Position:= 0;
         //Use stream to insert in a database or create a image or whatever the stream represent
         LApply.Values[0].Next;
        end;
       result:= true;
      end else result:= false;
     end;
    

    【讨论】:

    • 感谢 Fornés 先生,我们正在搜索的行代码是:{(FDMemUp.FieldByName('IMAGE') as TBlobField).LoadFromStream(mes);}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 2011-06-27
    • 2013-07-08
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多