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 里面还可以继续使用。

你可能感兴趣的:(FireDAC,Delphi)