2015/03/09

ADO 是個好東西,不用嗎?

ADO--ActiveX Data Object

在RAD Studio裡被歸類在「ADO Express」元件盤中,RAD Studio 2006後則改名為「dbGo」。

ADO架構
圖片來源:MSDN Microsoft Data Development Technologies: Past, Present, and Future


ADO的缺點在於,全世界的作業系統中,只有Windows才有具備Ole Provider。

換言之,ADO只能運行在Windows的世界。

然而在深入了解ADO後,發現ADO的核心概念和DataSnap幾乎一樣,透過Windows平台內建的OleDB engine,要單層開發、兩層開發,有狀態還是無狀態形式的公事包開發都不是問題,一切只需要一個ADO元件就可以完成。

ADO是個好東西,不用嗎?

單機,對於Access、Excel都有非常多的範例和很極佳的效能。
兩層,對於SQL Server的連線效能極佳,又額外提供其它資料庫的Ole Provider可以擴充。

無狀態的儲存,我們可以採用「公事包」的方式,把ADODataSet的Data另存為實體檔案,待網路順暢時再行傳輸。

「公事包」這名詞,微軟是這麼說的:

使用公事包同步 -- Windows 7 說明
您可以使用 [公事包] 來讓兩部不同電腦之間的檔案保持同步,即使電腦不在相同的網路上。 如果電腦不在相同的網路上,您可以使用卸除式媒體從一部電腦將檔案複製到另一部電腦,再使用另一部電腦處理那些檔案,然後使用 [公事包] 對原始電腦進行變更同步。

ADO 裡的 LockType 中,ltBatchOptimistic 參數便是對應公事包特性。
更淺碟一點的說法,就是「離線編輯」。

實際的範例用法如下:
dfm:

object ADOConnection1: TADOConnection
  Connected = True
  ConnectionString =
    'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=root;' +
    'Initial Catalog=AdventureWorks;Data Source=127.0.0.1;password=ILoveEden!'
  KeepConnection = False
  LoginPrompt = False
  Mode = cmReadWrite
  Provider = 'SQLOLEDB.1'
  Left = 60
  Top = 34
end
object DBNavigator1: TDBNavigator
  Left = 42
  Top = 25
  Width = 240
  Height = 25
  DataSource = DataSource1
  TabOrder = 0
end
object ADODataSet1: TADODataSet
  Active = True
  Connection = ADOConnection1
  CursorType = ctStatic
  LockType = ltBatchOptimistic
  CommandText = 'select * from Emp'
  Parameters = <>
  Left = 60
  Top = 86
end
object DataSource1: TDataSource
  DataSet = ADODataSet1
  Left = 58
  Top = 136
end
object DBGrid1: TDBGrid
  Left = 12
  Top = 62
  Width = 379
  Height = 171
  DataSource = DataSource1
  TabOrder = 1
  TitleFont.Charset = DEFAULT_CHARSET
  TitleFont.Color = clWindowText
  TitleFont.Height = -11
  TitleFont.Name = 'Tahoma'
  TitleFont.Style = []
end
object TrackBar1: TTrackBar
  Left = 464
  Top = 13
  Width = 79
  Height = 32
  Max = 1
  Position = 1
  TabOrder = 2
  OnChange = TrackBar1Change
end
object Label1: TLabel
  Left = 406
  Top = 23
  Width = 52
  Height = 13
  Caption = 'Connected'
end
object CheckBox1: TCheckBox
  Left = 406
  Top = 56
  Width = 97
  Height = 17
  Caption = 'Offline Mode'
  TabOrder = 3
  OnClick = CheckBox1Click
end
object Button1: TButton
  Left = 410
  Top = 86
  Width = 75
  Height = 25
  Caption = 'ApplyUpdate'
  TabOrder = 4
  OnClick = Button1Click
end
object Button2: TButton
  Left = 410
  Top = 122
  Width = 101
  Height = 25
  Caption = 'Save Package'
  TabOrder = 5
  OnClick = Button2Click
end
object Button3: TButton
  Left = 410
  Top = 153
  Width = 101
  Height = 25
  Caption = 'Load Package'
  TabOrder = 6
  OnClick = Button3Click
end

Pas:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Grids, DBGrids, DB, ADODB, ExtCtrls, DBCtrls;

type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    DBNavigator1: TDBNavigator;
    ADODataSet1: TADODataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    TrackBar1: TTrackBar;
    Label1: TLabel;
    CheckBox1: TCheckBox;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure TrackBar1Change(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ADODataSet1.Connection := ADOConnection1;
  ADODataSet1.UpdateBatch;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ADODataSet1.SaveToFile('OfflinePackage.data');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ADODataSet1.Close();
  ADODataSet1.LoadFromFile('OfflinePackage.data');
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  ADODataSet1.Connection := nil;
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
  ADOConnection1.Connected := (TrackBar1.Position = 1);
  ADODataSet1.Active       := ADOConnection1.Connected;
end;

end.

成果圖:

ADO 公事包範例

故可從以上得知,ADO 真的是很棒的架構。

公司採用 SQL Server,以及沒有跨平台需求的專案,ADO 真的可以完全符合需求。

安全性則可以透過 VPN 和 NAT 來解決。



DataSnap 好像又不是這麼必要了。是嗎?

1 則留言: