Delphi 使用 Datasnap 進行三層應用開發,積累了幾種技術,總結如下:
1、(推薦!)在 Datasnap 服務端 使用 TDatasetProvider,客戶端 使用 TDSProviderConnection
1)采用 Datasnap Server ,可以使用TCP/IP、Http 通信。TDatasetProvider 能夠提供 “元數據與業務數據”。
推薦:采用(FireDac技術) TFDConnection 連接數據庫,通過 TFDQuery/TFDTable 向 TDatasetProvider 提供數據集;(!執持數據庫新版本)
注意:也可以采用(DBX技術)TSQLConnect、TSQLDataSet/TSQLQuery/TSQLTable/TSQLStoredProc,向 TDatasetProvider 提供數據集;
2)客戶端使用(DBExpress技術 DBX) TSQLConnection + TDSProviderConnection ==》TClientDataSet ==》TDataSource
TSQLConnection 設置為 DataSnapCONNECTION,驅動 DataSnap;
TDSProviderConnection 設置:TSQLConnection 的實例(驅動 DataSnap);ServerClassName 設置 DataSnap服務端 提供服務的 “類名稱”;
TClientDataSet 設置:RemoteServer 為 TDSProviderConnection 的實例,ProviderName 是服務端 的相應“類”下的 TDatasetProvider 實例。
提示1:(1 FRM)TClientDataSet 可以 綁定 TStringGrid ,或者 (2 VCL)通過增加 TDataSource 連接 TDBGrid 。
提示2:客戶端 TClientDataSet 的變更,如何返回服務器端,以及客戶端數據集的查詢、排序、過濾等,
建議參考《Delphi2006-DbExpress高效數據庫開發》這本書;《Delphi 10.1 Berlin DataSnap 開發手冊》第一章也有介紹本項技術。
3)好像一個TDatasetProvider,只能提供一個Dataset,如果要建立 主Master/從Detail 數據集,需要采用下列方式:
利用 TFDQuery 建立兩數據集,一個是 主Master ,另一個的 Masterdata 屬性設置為主數據集。
4)(好,供參考!)服務端 可以只用一個:TFDConnection + TFDQuery + TDatasetProvider 向客戶端提供數據,
但 TDatasetProvider 的屬性 Options 選擇 poAllowCommandText 為 True ,即允許 TFDQuery 不管理其SQL 的值,
直接從客戶端 接收 SQL ,並向客戶端返回 查詢數據集。
客戶端 的 TClientDataSet 通過 CommandText 屬性設置 SQL 命令,可以帶參數,並從Params 獲取參數值,將SQL發給服務端,並接收返回數據。
這樣,可以一個服務端 TDatasetProvider ,服務多個客戶端。當然,會話 Session 采用 一次性的比較合適,或者 獲取數據完成,斷開 SQLConn連接。
參考《DataSnap ClientdataSet 三層中主從表的操作》搞定主從表的設置!!!
2、在 Datasnap 服務端 使用 TFDQuery,客戶端 使用 TSQLConnection 或者 TDSRestConnection ,數據交換用 TStream
參考:http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/DataSnap.FireDAC_DBX_Sample (DataSnap 聯合 FireDAC)
1)采用 Datasnap Server ,可以使用TCP/IP、Http 通信。
TFDConnection 連接數據庫,通過 TFDQuery (設置 + TFDSchemaAdapter) 提供數據集 , ==》TDataSource (主)
通過 TFDQuery (設置 + TFDSchemaAdapter,設置 MasterSource 、MasterFields 為 “主數據源/ID”) 提供數據集 ,
==》TDataSource (從)
公開服務類(Class)的 發送數據集方法 ,以 TStream 類型的方式 ,借助 TFDSchemaAdapter 發送數據,接收更新、並寫入數據庫。
function TServerMethods.StreamGet: TStream;
begin
Result := TMemoryStream.Create;
try
qCustomers.Close; //主數據集
qCustomers.Open;
qOrders.Close; //從數據集
qOrders.Open;
FDSchemaAdapter.SaveToStream(Result, TFDStorageFormat.sfBinary);
Result.Position := 0;
finally
//
end;
end;
以及 接收方法:
function TServerMethods.StreamPost(AStream: TStream): string;
var
LMemStream: TMemoryStream;
LErrors: Integer;
begin
Result := '';
// 獲取 數據流 從客戶端 Retreive entire stream from client
LMemStream := CopyStream(AStream); //復制 數據流
LMemStream.Position := 0;
try
FDSchemaAdapter.LoadFromStream(LMemStream, TFDStorageFormat.sfBinary);
LErrors := FDSchemaAdapter.ApplyUpdates
finally
LMemStream.Free;
if LErrors > 0 then
Result := Format(sErrorsOnApplyUpdates , [GenerateErrorMessage]);
end;
end;
2)客戶端 可以采用兩種 連接方式:1)TSQLConnection (DBX 方式);2)TDSRestConnection (Rest方式)
通過兩者(右點)可以 生成 服務端代理類 (Generate Datasnap Client Classes),調用 代理類的方法,獲取 服務端數據流。
TFDTableAdapter (+ 同一 TFDSchemaAdapter,設置 DatSTableName 為服務端 的 TFDQuery 名 ) ==》 TMemTable ==》 TDataSource (主 -- 客戶)
TFDTableAdapter (+ 同一 TFDSchemaAdapter)設置 DatSTableName 為服務端 的 TFDQuery 名) ==》 TMemTable ==》 TDataSource (從 -- 訂單)
如何 獲取數據 ,參考 示例!(省略。。。) 綁定GRID 。
LMemStream := TServerMethodsClient(ServerConnection).StreamGet 代理類通過連接組件,獲取服務端 數據流 TStream;
FDSchemaAdapter.LoadFromStream(LMemStream, TFDStorageFormat.sfBinary) 從流中加載 數據集。
3、(考慮!)應用 Rest Datasnap 服務端 ,Http通信, TFDJsonDataSets 與 TFDJsonDelta 格式交換數據
示例 第9章3節 (9.3) 使用TFDJsonDataSets 功能 參考《Delphi 10.1 Berlin DataSnap 開發手冊》
4、(推薦)使用 Rest Client 連接 Restful 服務,不限定於(Delphi 產生的),關注 :TRESTResponseDataSetAdapter 的應用。
《Delphi 10.1 Berlin FireDAC 數據庫開發手冊》 P109 第 3-1-2 章節 介紹了應用 ,使用 TFDMemTable 處理 Rest 獲得的數據。
使用 TRESTResponseDataSetAdapter 將 TRESTResponse數據提供給 TFDMemTable ,包含了 元數據信息。
官方示例 : http://docwiki.embarcadero.com/RADStudio/Tokyo/en/REST_Client_Library