FireDAC 學習 - 5:三層,遠程提交,公文包模式

問題需求:

以前版本的 Delphi,三層架構的程序,採用 TClientDataSet 來作爲客戶端的內存表,所有用戶操作都是針對 TClientDataSet 裏面的記錄進行增刪改的操作。在這裏,用戶修改後的記錄,叫做 Delta。操作完成後,可以實現以下功能:

1. 將用戶增刪查改從 ClientDataSet 裏面讀取出來,也即是 ClientDataSet.Delta,這是一個 Variant 類型的數據。通過網絡通訊將這個數據傳遞給服務器端,服務器端可以直接把它賦予到一個服務器端的 ClientDataSet,也就是在服務器端執行 ClientDataSet1.Delta := MyDelta;然後在服務器端對這個 ClientDataset1 執行 ApplyUpdates,這個位於服務器端的 ClientDataSet1 就可以通過它關聯的 DataSetProvider 將 Delta 的內容提交到數據庫服務器。默認情況下是 DataSetProvider 內部的代碼根據 Delta 的內容自動創建 SQL 語句,通過 SQL 語句去將更新的數據提交到服務器。

2. 客戶端的 ClientDataset 裏面的數據,包括增刪改的記錄(也就是 Delta),都可以通過 SaveToFile 的方式保存爲客戶端本地文件。這樣當客戶端離線(和服務器之間網絡不通)的時候,用戶可以在客戶端進行操作,操作完成後保存爲本地文件。下次運行程序時,從本地文件加載數據,用戶可以繼續操作。然後當客戶端網絡能夠連接服務器時,用戶可以提交數據到服務器端。這裏提交的實際上就是上面說的 Delta 數據。這種操作叫公文包模式。也就是客戶端可以離線操作。

FireDAC 對應的方式:

上述兩個功能,在 FireDAC 裏面,有對應的方法可以實現。

遠程提交:

1. 首先從數據庫服務器獲取數據,用 FdQuery1 打開數據庫的一個表獲得數據;

2. 通過 FdQuery1.SaveToStream(AStream); 的方式將數據輸出給一個 Stream,然後通過網絡將 Stream 送到客戶端,客戶端的 FdMemTable1.LoadFromStream(AStream) 加載數據,用戶可以在客戶端看到數據,進行編輯操作;

3. 用戶編輯操作完後,如果想將客戶編輯的數據提交給服務器端,需要做以下的操作:

3.1. 首先設置 FdMemTable1 的屬性,使得它只輸出 Delta 而不是全部數據,這樣可以降低網絡流量,屬性設置如下:

FdMemTable2.ResourceOptions.StoreItems := FdMemTable2.ResourceOptions.StoreItems - [siData];

上述屬性可以在設計期的屬性面板裏面找到,默認是包含 siData 的,去掉後,就只輸出 Delta 了;

3.2. 通過以下語句輸出 Delta 到一個 Stream:

FdMemTable2.SaveToStream(AStream);

3.3. 將這個 Stream 通過網絡傳送到服務器端,由服務器端的 FdQuery1 直接加載後,提交。這裏省去了 MIDAS 裏面的 DataSetProvider。語句如下:

    FdQuery1.LoadFromStream(AStream);
    FdQuery1.ApplyUpdates(0);

3.4. 要執行上述語句,必須設置 FdQuery1 的 CachedUpdates 爲 True,默認是 False 的。

3.5. 客戶端如果提交成功,需要執行 FdMemTable2.MergeChangeLog; 否則客戶端的 FdMemTable2 仍然存在已經提交成功的 Delta。

本地保存:

上述過程,用戶在客戶端編輯操作完成後,如果網絡原因導致無法提交,如果是普通網頁版本的軟件,關閉瀏覽器以後,之前輸入的數據就沒有了,白乾活。如果客戶端是DELPHI 的 MIDAS 的或者 FireDAC 的,則可以將用戶的編輯操作保存爲本地文件,下次打開電腦接着幹活。

1. 用戶編輯完成後,執行以下語句:

FdMemTable2.ResourceOptions.StoreItems := FdMemTable2.ResourceOptions.StoreItems + [siData];
FdMemTable2.SaveToFile(GetFileDataName);

保存的時候,要保證 StoreItems 屬性裏面,有 siData 這樣保存的文件裏面有全部數據,也包括了對記錄的改變(Delta)的數據。本地保存後,用戶可以關閉程序,關閉電腦。

2. 下次用戶打開程序,執行:

FdMemTable2.LoadFromFile(GetFileDataName);

則客戶端程序加載了本地的數據,用戶可以繼續工作,對數據進行查看、增刪改。

3. 客戶端加載了本地數據後,如果這個時候能夠連接服務器端,則同樣可以提交客戶端的 Delta 到服務器端,將用戶對數據的操作保存到數據庫服務器裏面。

---------------------- 分割線 -------------------------

總結一下:

使用 Delphi 做數據庫的三層架構的程序,大概就是:

1. 開發一個服務器端程序,連接數據庫。服務器端程序負責從數據庫服務器獲得數據,也負責將數據提交給數據庫服務器。

2. 開發一個客戶端程序,客戶端程序的數據從服務器端程序獲取。客戶端程序呈現操作界面給用戶。用戶在客戶端程序上對數據的增刪改操作,最終輸出爲一個 Delta 數據。客戶端將這個 Delta 數據通過網絡發送給服務器端,服務器端再將這個 Delta 數據變成 SQL 語句去提交給數據庫服務器。

3. 上述通過網絡傳遞數據的方法,如果採用 Delphi 提供的現成框架,之前有 WebServices 框架,現在有 DataSnap 框架。當然也有一些第三方的框架,也可以自己寫網絡傳輸的代碼。

實現上述方法,在數據庫層面,之前的 Delphi 採用 MIDAS 框架,涉及到的控件包括:

1. 數據庫讀取控件,比如 DBExpress 或者 ADO 甚至可以是 FireDAC;

2. 服務器端用於輸出數據的 TDataSetProvider;

3. 客戶端用於緩存數據給用戶操作的 TClientDataSet;

實現上述方法,如果不使用 MIDAS 而是隻用 FireDAC,涉及到的控件包括:

1. 數據庫讀取控件 TFdQuery;

2. 客戶端用於緩存數據給用戶操作的控件 TFdMemTable。

--------------------------------------

到這裏,基本上 MIDAS 能做的,只使用 FireDAC 也能做到了。難怪 Delphi 開始提倡用 FireDAC,拋棄 MIDAS 了。當然,MIDAS 在新版 DELPHI 裏面還可以繼續使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章