張捍衛(wèi) 余升
摘要:在開發(fā)Web應(yīng)用程序時(shí),經(jīng)常要對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問,實(shí)現(xiàn)對(duì)數(shù)據(jù)的增加、刪除、修改等操作。這一系列操作代碼是煩瑣的,而且每次對(duì)數(shù)據(jù)庫(kù)操作都要重復(fù)編寫這些代碼。該文介紹了運(yùn)用.NET技術(shù)和數(shù)據(jù)庫(kù)技術(shù)編寫通用代碼,用較短的程序代替通常需要重復(fù)書寫的大量程序段,減少了數(shù)據(jù)庫(kù)維護(hù)的工作量,提高了項(xiàng)目開發(fā)的效率。
關(guān)鍵詞:.NET技術(shù);數(shù)據(jù)庫(kù);通用維護(hù)
中圖分類號(hào):TP391 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2014)01-0014-02
在SQL Server數(shù)據(jù)庫(kù)系統(tǒng)開發(fā)中,經(jīng)常要處理多個(gè)數(shù)據(jù)表,對(duì)于這些數(shù)據(jù)表一般都需要編寫程序,實(shí)現(xiàn)數(shù)據(jù)的添加、修改和刪除等維護(hù)操作。這些操作方法步驟相同,不同的只是表的名稱、字段名稱和數(shù)據(jù)類型等,但每次需要重復(fù)的編寫這些代碼,導(dǎo)致程序不能適應(yīng)用戶需求的變化,缺乏靈活性,對(duì)數(shù)據(jù)庫(kù)結(jié)構(gòu)調(diào)整的適應(yīng)能力不強(qiáng),進(jìn)而影響到項(xiàng)目開發(fā)的效率、進(jìn)度和開發(fā)質(zhì)量。該文介紹的數(shù)據(jù)庫(kù)通用維護(hù)操作模塊在Visual Studio .NET環(huán)境下實(shí)現(xiàn),為解決多數(shù)據(jù)表的通用維護(hù)操作提供了一個(gè)較好的解決方案,并通過(guò)一系列的測(cè)試與應(yīng)用,證明這種方案具有一定的實(shí)用價(jià)值。
1 實(shí)現(xiàn)思想
在SQL Server數(shù)據(jù)庫(kù)中,對(duì)數(shù)據(jù)庫(kù)的維護(hù)操作是通過(guò)結(jié)構(gòu)化查詢語(yǔ)言SQL進(jìn)行的。添加記錄是由Insert語(yǔ)句完成的,其基本的形式為:Insert Into 表名 (字段名列表) Values (值列表);修改記錄語(yǔ)句是:Update 表名 set 修正式列表 where 條件;刪除記錄的語(yǔ)句是:Delete from 表名 where 條件??梢钥闯?,把表名、字段名或字段的值傳遞給維護(hù)記錄的方法,就能實(shí)現(xiàn)數(shù)據(jù)的通用維護(hù)操作。
維護(hù)記錄的方法就是利用傳遞過(guò)來(lái)的參數(shù),自動(dòng)獲取字段信息,生成SQL語(yǔ)句,完成相應(yīng)的操作。字段信息的獲取可以通過(guò)SQL Server提供的系統(tǒng)視圖來(lái)實(shí)現(xiàn),INFORMATION_SCHEMA.COLUMNS系統(tǒng)視圖,就存有當(dāng)前數(shù)據(jù)庫(kù)中用戶可以訪問的所有數(shù)據(jù)表的字段信息,其中的部分信息如表1所示。在設(shè)計(jì)時(shí),只要知道要訪問的數(shù)據(jù)表名稱,就能獲得該表的結(jié)構(gòu)信息。
表1 系統(tǒng)視圖information_schema.columns部分字段信息
[字段名\&字段類型\&說(shuō)明\&TABLE_NAME\&nvarchar(128)\&表的名稱\&COLUMN_NAME\&nvarchar(128)\&表中字段名稱\&DATA_TYPE\&nvarchar(128)\&表中字段數(shù)據(jù)類型\&CHARACTER_MAXIMUM_LENGTH\∫\&字符型字段最大字符數(shù)\&COLUMN_DEFAULT\&nvarchar(4000)\&字段缺省值\&]
2 實(shí)現(xiàn)方法
2.1 傳遞字段
傳遞字段主要是字段名及字段值的傳遞,可以采用二維字符串?dāng)?shù)組,也可以使用Hash表來(lái)實(shí)現(xiàn)。Hash表,也叫散列表,表示鍵/值對(duì)的集合,是根據(jù)關(guān)鍵詞/值(Key,value)直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。使用Hash表的一個(gè)優(yōu)點(diǎn)是關(guān)鍵詞不允許重復(fù),這樣可以避免書寫失誤造成字段名重復(fù)的問題。在數(shù)據(jù)增加頁(yè)面中,將要操作的數(shù)據(jù)表的字段名以及相對(duì)應(yīng)的字段值,添加到Hash表中,然后在調(diào)用增加記錄的方法時(shí)作為實(shí)參傳遞過(guò)去。
定義Hash表對(duì)象:Hashtable hash = new Hashtable();
向Hash表中添加元素的方法:hash.Add("字段名", "字段值");
調(diào)用增加記錄的方法:由于dbAdd(string, Hashtable)被定義成類的靜態(tài)方法,所以調(diào)用語(yǔ)句的形式為:
類名.dbAdd("表名", hash);
2.2 連接數(shù)據(jù)庫(kù)
從Web.Config配置文件中獲取數(shù)據(jù)庫(kù)連接字符串,創(chuàng)建SqlConnection對(duì)象,并返回該對(duì)象。
Public static SqlConnection conn()
{ string strConn =ConfigurationManager.ConnectionStrings["SQLConnectionString"].ToString();
SqlConnection con = new SqlConnection(strConn); return con; }
2.3 獲取字段信息
下述代碼是獲取字段的信息,方法中有兩個(gè)參數(shù),tablename是數(shù)據(jù)表名,columnName是字段名。執(zhí)行時(shí),從information_schema.columns視圖中獲取數(shù)據(jù)表指定字段的信息,并將獲取的結(jié)果保存在SqlDataReader對(duì)象dr中,并返回dr。
private static SqlDataReader getColummTypeAndLength(string tablename, string columnName)
{ SqlConnection con = conn();//創(chuàng)建連接
string cmdText = "Select * from information_schema.columns where TABLE_NAME=@Table_Name and COLUMN_NAME=@Column_Name";
SqlCommand cmd = new SqlCommand(cmdText, con); //創(chuàng)建SqlCommand
//創(chuàng)建參數(shù)并賦值
cmd.Parameters.Add("@Table_Name", SqlDbType.NVarChar, 128);
cmd.Parameters.Add("@Column_Name", SqlDbType.NVarChar, 128);
cmd.Parameters[0].Value = tablename; cmd.Parameters[1].Value = columnName;
SqlDataReader dr; //定義SqlDataReader
con.Open(); //打開連接
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); //執(zhí)行并關(guān)閉對(duì)象
return dr; }
2.4 添加記錄
添加記錄方法dbAdd(string tablename, Hashtable hashTable)是將記錄添加到數(shù)據(jù)庫(kù)中,該方法有兩個(gè)參數(shù),tablename是數(shù)據(jù)表名, hashTable是Hash表對(duì)象,即保存有字段名及值的集合。方法中還定義了兩個(gè)字符串變量:sql1, sql2 分別存放字段名列表和字段值參數(shù)列表。運(yùn)行時(shí)從Hash表中依次循環(huán),每次取出一個(gè)元素后,調(diào)用getColummTypeAndLength(string tablename, string columnName)方法,獲取字段的類型及長(zhǎng)度等,形成字段列表、字段值參數(shù)列表,以及參數(shù)類型的定義和參數(shù)值的設(shè)置,最終形成插入記錄的SQL語(yǔ)句后,打開數(shù)據(jù)庫(kù)連接,執(zhí)行添加操作。如果操作成功,返回大于0的值,否則返回-1。
public static int dbAdd(string tablename, Hashtable hashTable)
{ SqlConnection con = conn();//創(chuàng)建連接
SqlCommand cmd = new SqlCommand();
string sql1 = "", sql2 = "";
foreach (DictionaryEntry entry in hashTable)
{ SqlDataReader dr = getColummTypeAndLength(tablename, entry.Key.ToString());
if (dr != null) {
string colName = entry.Key.ToString();
string colParaName = "@" + entry.Key.ToString();
sql1 += colName + ","; sql2 += colParaName + ","; //生成字段名和值列表
if (dr.Read()) { //設(shè)置參數(shù)類型及參數(shù)值
switch (dr["DATA_TYPE"].ToString()){
case "varchar":
int col_len=int.Parse(dr["CHARACTER_MAXIMUM_LENGTH"].ToString());
cmd.Parameters.Add(new SqlParameter(colParaName, SqlDbType.VarChar,col_len ));
cmd.Parameters[colParaName].Value = entry.Value.ToString(); break;
case "int":
cmd.Parameters.Add(new SqlParameter(colParaName, SqlDbType.Int)); (下轉(zhuǎn)第19頁(yè))
(上接第15頁(yè))
cmd.Parameters[colParaName].Value = int.Parse(entry.Value.ToString()); break;
//由于篇幅所限,添加其它字段類型參數(shù)這里省略 }}
dr.Close(); }}
sql1 = sql1.Substring(0, sql1.Length - 1); //去掉字段名最后的逗號(hào)
sql2 = sql2.Substring(0, sql2.Length - 1); //去掉參數(shù)最后的逗號(hào)
cmd.CommandText = "Insert Into "+tablename+ " ("+sql1 + ") Values (" + sql2+")";
cmd.Connection = con; int result = -1; con.Open();
result = cmd.ExecuteNonQuery(); con.Close(); return result;}
2.5 添加引用
在編寫代碼過(guò)程中,由于使用了數(shù)據(jù)庫(kù)、Hash表和Web配置文件,所以除系統(tǒng)默認(rèn)的命名空間外,還要引入System.Data.SqlClient、System.Collections和System.Configuration命名空間。
3 結(jié)束語(yǔ)
上述介紹的是數(shù)據(jù)添加的實(shí)現(xiàn)過(guò)程,修改記錄的方法與此類似,刪除記錄則相對(duì)簡(jiǎn)單,只要理解了該方法的實(shí)現(xiàn)過(guò)程,一定能完成修改和刪除記錄的操作。實(shí)踐證明,該數(shù)據(jù)庫(kù)通用維護(hù)代碼的使用,實(shí)現(xiàn)了在各種表上進(jìn)行插入、刪除和更新數(shù)據(jù)操作,對(duì)于項(xiàng)目開發(fā)效率,程序代碼復(fù)用性、開發(fā)質(zhì)量等都會(huì)得到極大的提高。
參考文獻(xiàn):
[1] 張彥.利用ASP技術(shù)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的通用維護(hù)[J].福建電腦,2003(3):37.
[2] 王緩緩,李虎.使用設(shè)計(jì)模式構(gòu)建基于.NET的通用數(shù)據(jù)庫(kù)訪問層[J].計(jì)算機(jī)與現(xiàn)代化,2005,113(1):29-32.
[3] 李萬(wàn)寶.ASP.NET企業(yè)級(jí)開發(fā)案例精解(C#)[M].北京:中國(guó)林業(yè)出版社,2005.