Delphi7下仿Ado.Net類的實現 (轉)

gugu99發表於2007-11-27
Delphi7下仿Ado.Net類的實現 (轉)[@more@]

7下仿類的實現

to:kaneboy@163.net">kaneboy@163.net

:namespace prefix = o ns = "urn:schemas--com::office" />

最近正在學.Net,發現.Net下的Ado.Net資料(方式和理念都)比Ado要先進很多,天生可以用於MultiTier環境,透過繼承DataSet,能很方便建立可以在各層(主要是DataAccess層和BusinessRule層)間傳遞的實體,而且斷開式的連線方式,可以很大的節省連線資源,同時在客戶端又可以方便的處理存於物件中的資料。

由於一直是在使用Delphi,感覺很多以前在Delphi下感覺束縛的方法,透過Ado.Net,可以非常方便的解決,於是想到其實可以透過模仿Ado.Net的運作,在Delphi下自己來部分實現的。

下面對各單元和各類做簡單講解,不包含類中所有的公開介面,請參看原始碼。

一、DataColumn單元

實現了TDataColumn類、TDataColumnCollection類、TDataColumnState類、TDataColumnCollectionState類。

TDataColumn用來儲存資料表中一列的資訊(包括資料),ColumnName屬性公開列名(自定義的,不同於資料庫中的物理欄位名),FieldName屬性公開資料庫中的欄位名,DataType屬性公開欄位的資料型別,OriginValue、OldValue、CurrentValue屬性分別公開此列的初始值(從資料庫中取出資料時的值)、舊值和當前值,Value屬性直接返回CurrentValue,這些屬性都返回Variant型別的值,為了方便使用,AsString、AsDataTime、AsInteger和其他類似的屬性直接返回對應型別的值。

TDataColumnCollection是集合類,繼承自TList,用來儲存多個TDataColumn物件,過載了Add,Insert方法以實現型別檢查。

TDataColumnState是一個列舉類,用來表示一個TDataColumn的狀態,分別有csUnKnown, csUnChanged, csModified,用來表示未知、未改變、已改變三種狀態。

TDataColumnCollectionState也是列舉類,用來表示一個TDataColumnCollection的狀態,分別有ccsUnknown, ccsUnChanged, ccsModified。

二、DataRow單元

實現了TDataRow類、TDataRowCollection類、TDataRowState類。

TDataRow用來儲存資料表中的一行資料,Columns屬性是一個TDataColumnCollection型別的值,返回了這行中包含的所有列。

TDataRowCollection是集合類,用來維護多個TDataRow物件。

TDataRowState列舉類用來表示一個資料行的狀態,有rsUnknown, rsUnChanged, rsNew, rsModified, rsDeleted。

三、DataCommand單元和DataCommandParameter單元

由於TAdoCommand未能符合要求,所以對其進行繼承,以擴充其特性。

這兩個單元實現TDataCommand類、TDataCommandParameter類、TDataCommandParameterCollection類、TDataCommandParameterType類。

TDataCommandParameter類用來表示一個TDataCommand的引數,這個引數資訊用來輔助TDataCommand的CommandText實現各種操作。DataType屬性公開參數列示的資料列的資料型別,FieldName屬性公開物理資料庫中的欄位名,Name屬性公開引數名,ParamType屬性是一個TDataCommandParameterType列舉型別的值,可以是ptUpdateField或ptWhereField,表示引數是一個值還是定位值。

TDataCommandParameterCollection是集合類,表示多個TDataCommandParameter物件。

TDataCommand繼承自TAdoCommand,DataParameters屬性公開一個TDataCommandParameterCollection型別的值,表示一個引數集合。

四、DataTable單元

實現了TDataTable和TDataTableCollection類。

TDataTable表示一個資料表,Columns屬性公開表的列集合,Rows屬性公開表的行集合,NewRow()用來新增一個屬於本表的TDataRow,並返回之,TableName屬性返回表名,BindTo()方法可以直接把這個TDataTable繫結到一個TStringGrid,另外一個過載的BindTo()把一列的資料繫結到一個TStringList上。

TDataTableCollection是一個表示多個表的集合類。

五、DataSetPlus單元

實現了TDataSetPlus類。(為什麼不直接用TDataSet這個名字呢?因為Delphi中已經自己用了:)

TDataSetPlus表示一個資料集,可以包含多個資料表,Tables屬性公開其包含的TDataTable物件,NewTable()方法新增一個屬於自身的資料表。

六、DataAdapter單元

實現TDataAdapter類,用來連線TDataSetPlus和資料庫。

TDataAdapter類,可以填充或更新一個資料集,Command、InsertCommand、UpdateCommand、DeleteCommand屬性分別公開四個TDataCommand型別的值,用來進行取資料、插入資料、更新資料、刪除資料的操作,Fill()方法可以根據SelectCommand中的CommandText把相應的資料填充進引數中的TDataSetPlus物件中,Update()方法可以根據InsertCommand、UpdateCommand、DeleteCommand把引數中的TDataSetPlus物件更新回資料庫。

最後,我們就可以這樣使用了:

var

  ds : TDataSetPlus;

  ada : TDataAdapter;

  cmdSelect, cmdInsert, cmdUpdate, cmdDelete : TDataCommand;

   conn : TAdoConnection;

  i : Integer;

begin

  // 定義資料庫連線

  conn := TAdoConnection.Create(nil);

  conn.ConnectionString := 'FILE NAME=.ado+.udl';

  conn.LoginPrompt := False;

  // 下面分別定義四個TDataCommand,用於Select, Insert, Update, Delete

  cmdSelect := TDataCommand.Create(nil);

  cmdSelect.Connection := conn;

  cmdSelect.CommandText := 'select username,pass from user';

  cmdInsert := TDataCommand.Create(nil);

  cmdInsert.Connection := conn;

  cmdInsert.CommandText := 'insert into userdb (username, password) values (@username, @password)';

  // 新增引數,用來表示要更新或定位的值

  cmdInsert.DataParameters.Add(TDataCommandParameter.Create('@username', 'username', ftString));

  cmdInsert.DataParameters.Add(TDataCommandParameter.Create('@password', 'password', ftString));

  cmdDelete := TDataCommand.Create(nil);

  cmdDelete.Connection := conn;

  cmdDelete.CommandText := 'delete from userdb where username=@username';

  cmdDelete.DataParameters.Add(TDataCommandParameter.Create('@username', 'username', ftString));

  cmdUpdate := TDataCommand.Create(nil);

  cmdUpdate.Connection := conn;

  cmdUpdate.CommandText := 'update userdb set password=@password where username=@username';

  cmdUpdate.DataParameters.Add(TDataCommandParameter.Create('@password', 'password', ftString));

  cmdUpdate.DataParameters.Add(TDataCommandParameter.Create('@username', 'username', ftString, ptWhereField));

  // 定義一個資料介面卡,初始化其Command屬性

  ada := TDataAdapter.Create();

  ada.SelectCommand := cmdSelect;

  ada.InsertCommand := cmdInsert;

  ada.UpdateCommand := cmdUpdate;

  ada.DeleteCommand := cmdDelete;

  // 定義一個資料集

  ds := TDataSetPlus.Create();

  conn.Open();

  // 用介面卡填充記錄集,自動新增一個叫’UserTable’的資料表放入記錄集中

  ada.Fill(ds, 'UserTable');

  // 示範更改記錄集中的資料

  for i := 0 to ds.Tables.ItemByName['UserTable'].Rows.Count-1 do

  begin

  ds.Tables.ItemByName['UserTable'].Rows[i].Columns.ItemByFieldName['password'].Value := '12345';

  end;

  // 用介面卡把記錄集中的更改更新回資料庫

  ada.Update(ds.Tables[0]);

  conn.Close();

  FreeAndNil(conn);

  FreeAndNil(ada);

  FreeAndNil(ds);

  FreeAndNil(cmdSelect);

  FreeAndNil(cmdInsert);

  FreeAndNil(cmdUpdate);

  FreeAndNil(cmdDelete);

end;

大家可以看到,存在很多缺陷,還有隱藏的(我基本上沒有做找Bug的動作),我只是把心裡想的先試驗一下,實現出來,如果有時間,再進行DeBug和完善。

已經想到要完善的:

1、實現CommandBuilder,如果只是對單個物理表做操作,可以根據SelectCommand自動生成InsertCommand、UpdateCommand和DeleteCommand。這是Ado.Net的方式,在很多場合下,可以節省大量的程式碼和時間。

2、更多的資料繫結。如,可以把指定的資料表中的一列的資料繫結到一個ComboBox。

3、……

整個原始碼可以在。

有什麼想法,請聯絡,,Thanks For 意見和批評。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-985335/,如需轉載,請註明出處,否則將追究法律責任。

相關文章