柏林版的DataSnap

在發表RAD Studio柏林版介紹到DataSnap功能時,英巴的文件只說柏林版的DataSnap除了改bug之外,就是開始移除Indy並改用THTTPClient等新的HTTP相關類別, 另外又隱約提到一個類別TDBXJSONStream,它可使用在DataSnap服務方法中. 第1次看到TDBXJSONStream時感覺有點陌生,但從它的名稱可大約猜出它應該是一個使用在dbExpress(DBX?)應用中的相關類別並提供JSON串列流的功能(JSONStream?).

嗯, 我很好奇的在IDE中搜尋TDBXJSONStream,並在Data.DBXCommon程式單元中找到了它, TDBXJSONStream是一個新類別,我並沒有在以前的版本中看到它.查看它的程式碼發現它提供了JSON Reader和Writer, 那麼這代表它提了寫入JSON物件和讀取JSON物件的功能.

property Reader: TJSONReader read GetJSONReader;

property Writer: TJSONWriter read GetJSONWriter;

此外它又有一個TStream物件特性, OK, 那麼它一定可以在此TStream物件中寫入和讀出JSON物件, 而這些功能也正是它的名稱代表的意義.

property BaseStream: TStream read FBaseStream;

瞭解了它的功能之後我們就可以來看看如何使用它. 先建立一個DataSnap Server專案, 在其中定義一個QueryHotel方法, 請注意QueryHotel方法回傳的物件正是TDBXJSONStream:

function QueryHotel(const sName : String) : TDBXJSONStream;

此DataSnap Server專案使用FireDAC存取MS SQL Sevrer中的資料:

Snap2

QueryHotel方法展示了如何使用TDBXJSONStream物件, 要寫入JSON物件到TDBXJSONStream, 我們只需要使用它的Writer特性取得它的JSON Writer:

function TServerMethods1.QueryHotel(const sName: String): TDBXJSONStream;

var

  sSQL : String;

 

  procedure WritePair(const sProperty, sFieldName : String);

  begin

    Result.Writer.WritePropertyName(sProperty);

    Result.Writer.WriteValue(qryTheHotel.FieldByName(sFieldName).AsString);

  end;

begin

  Result := TDBXJSONStream.Create;

  sSQL := qryTheHotel.SQL.Text;

  sSQL := sSQL + “" + sName + ‘%"‘;

  qryTheHotel.SQL.Text := sSQL;

  qryTheHotel.Open();

  try

    Result.Writer.WriteStartArray;

    while (not qryTheHotel.Eof) do

    begin

      try

        Result.Writer.WriteStartObject;

        WritePair(‘名稱’, ‘STITLE’);

        WritePair(‘地址’, ‘ADDRESS’);

        WritePair(‘電話’, ‘MEMO_TEL’);

      finally

        Result.Writer.WriteEndObject;

        qryTheHotel.Next;

      end;

    end;

  finally

    Result.Writer.WriteEndArray;

    Result.Writer.Close;

    qryTheHotel.Close;

  end;

end;

編譯並執行此DataSnap Server之後就可以使用瀏覽器來試著呼叫QueryHotel方法, 下圖顯示成功的呼叫QueryHotel方法並取得由TDBXJSONStream物件回傳的JSON資料:

Snap1

當然我們也可以使用Windows/OSX/Android/iOS客戶端來呼叫QueryHotel方法.

下面的顯示了如何在客戶端呼叫QueryHotel方法, 取得TDBXJSONStream物件並藉由TDBXJSONStream物件中的JSONReader物件讀出在伺服端寫入的JSON資料:

procedure TForm5.Button1Click(Sender: TObject);

var

  aServer : TServerMethods1Client;

  js : TDBXJSONStream;

begin

  aServer := TServerMethods1Client.Create(Self.SQLConnection1.DBXConnection);

  try

    js := aServer.QueryHotel(Edit1.Text);

    js.Reader.Rewind;

    while (js.Reader.Read) do

    begin

      case js.Reader.TokenType of

        TJsonToken.StartArray:

        begin

          while (js.Reader.Read) do

          begin

            case js.Reader.TokenType of

              TJsonToken.PropertyName:

              begin

                ListView1.Items.Add.Text := js.Reader.Value.ToString + ‘ : ‘ + js.Reader.ReadAsString;

              end;

            end;

          end;

        end;

      end;

    end;

  finally

    aServer.Free;

  end;

end;

執行客戶端並開始查詢資料就可以看到下面的結果畫面:

Snap4

那麼為什麼要使用TDBXJSONStream類別呢? 我想方便是主因, 因為它已經把數個功能結合在一個類別中, 免除程式師自己使用多個類別. 另外我在英巴文件中找到的資料說的是TDBXJSONStream類別執行速度快. 嗯,我並沒有去測試這個說明的真正的意義, 但它真的很好用就是了.

Have Fun!

 

廣告
  1. #1 by jamesjuan on 2016 年 07 月 22 日 - 10:57:17

    這一定要按讚!

  2. #2 by 顾军帅 on 2016 年 10 月 27 日 - 03:02:53

    李维老师:
    您好,如果访问https://embarcadero.qcomgroup.com.tw/download/10/delphi10dbx.rar不能正常下载文档如何进行?

    • #3 by gordonliwei on 2016 年 10 月 27 日 - 03:51:05

      那是捷康的網站, 我不知道delphi10dbx.rar是什麼, 你應該詢問捷康.

  3. #4 by 顾军帅 on 2016 年 10 月 27 日 - 04:44:06

    它是您写的柏林版delphi10.1里面载入的下载地址 用于下载 C H I N E S D E M O . G D B这个示例数据库

  4. #5 by 顾军帅 on 2016 年 10 月 27 日 - 06:00:16

    不好意思,已经找到答案了,是因为我的疏忽,输入网址的时候,在http后面多写了一个字母s。

  5. #6 by 靠delphi討生活的loser on 2016 年 11 月 14 日 - 08:21:13

    李大師總算出現了,文章從2013年後空白了兩年到2016年總算又看到了,李大師還是在推懬delphi 嗎?
    之前有看到新聞說英巴好像不再繼續開發delphi還是要把它賣掉之類的, 請問delphi未來的命運跟走向,請問李大師知道是怎麼一回事嗎?謝謝!

    • #7 by gordonliwei on 2016 年 12 月 05 日 - 02:50:46

      我還在用Delphi中, 沒什麼問題.
      Delphi的未來英巴已經公佈了吧, Delphi For Linux是下一版的重心.

  6. #8 by Wyatt Wong on 2016 年 11 月 27 日 - 10:52:56

    When will be your next demo in Shenzhen ?

    • #9 by gordonliwei on 2016 年 12 月 05 日 - 02:52:58

      It is up to Embarcadero, I have no idea yet.

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: