數據訪問組件是一組通用的訪問數據庫的代碼在所有項目中都可以用一般不需要修改本節使用的是Microsoft提供的數據訪問助手其封裝很嚴密且應用簡單
首先要先添加一個類並命名為SqlHelper系統會提示是否將類放在App_Code文件夾中此時一定要選擇是因為放在此文件夾下系統會自動進行編譯程序員就可以直接使用無需另外編譯了
SqlHelper的目的是從數據庫獲得信息或將信息保存到數據庫本實例的SqlHelper主要功能如下
()執行不返回數據的TSql命令例如修改會員卡信息添加會員資料等
()返回一個字段的TSql命令例如獲取會員卡類型的積分規則
()返回一組數據例如獲取會員資料獲取所有會員卡類型等
()緩存參數列表在執行一條語句時可能有多個參數為了提高速度將參數緩存
()讀取緩存的參數
下面用圖表的方式描述SqlHelper類的功能如圖所示
在SqlHelper類中添加數據庫處理代碼如下
//編號
using System;
using System
Data;
using System
Configuration;
using System
Web;
using System
Web
Security;
using System
Collections;
using System
Data
SqlClient;
//編號
/**//// <summary>
/// 數據庫的通用訪問代碼
/// 此類為抽象類
不允許實例化
在應用時直接調用即可
/// </summary>
public abstract class SqlHelper
{
//獲取數據庫連接字符串
其屬於靜態變量且只讀
項目中所有文檔可以直接使用
但不能修改
//編號
public static readonly string ConnectionStringLocalTransaction =
ConfigurationManager
ConnectionStrings[
connstring
]
ConnectionString;
// 哈希表用來存儲緩存的參數信息
哈希表可以存儲任意類型的參數
//編號
private static Hashtable parmCache = Hashtable
Synchronized(new Hashtable());//編號
/**//// <summary>
///執行一個不需要返回值的SqlCommand命令
通過指定專用的連接字符串
/// 使用參數數組形式提供參數列表
/// </summary>
/// <remarks>
/// 使用示例
/// int result = ExecuteNonQuery(connString
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
connectionString
>一個有效的數據庫連接字符串</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個數值表示此SqlCommand命令執行後影響的行數</returns>
//編號
public static int ExecuteNonQuery(string connectionString
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
//編號
using (SqlConnection conn = new SqlConnection(connectionString))
{
//通過PrePareCommand方法將參數逐個加入到SqlCommand的參數集合中
PrepareCommand(cmd
conn
null
cmdType
cmdText
commandParameters);
int val = cmd
ExecuteNonQuery();
//清空SqlCommand中的參數列表
cmd
Parameters
Clear();
//編號
return val;
}
}
/**//// <summary>
///執行一條不返回結果的SqlCommand
通過一個已經存在的數據庫連接
/// 使用參數數組提供參數
/// </summary>
/// <remarks>
/// 使用示例
/// int result = ExecuteNonQuery(conn
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
conn
>一個現有的數據庫連接</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個數值表示此SqlCommand命令執行後影響的行數</returns>
//編號
public static int ExecuteNonQuery(SqlConnection connection
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd
connection
null
cmdType
cmdText
commandParameters);
int val = cmd
ExecuteNonQuery();
cmd
Parameters
Clear();
return val;
}
/**//// <summary>
/// 執行一條不返回結果的SqlCommand
通過一個已經存在的數據庫事物處理
/// 使用參數數組提供參數
/// </summary>
/// <remarks>
/// 使用示例
/// int result = ExecuteNonQuery(trans
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
trans
>一個存在的 sql 事物處理</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個數值表示此SqlCommand命令執行後影響的行數</returns>
//編號
public static int ExecuteNonQuery(SqlTransaction trans
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd
trans
Connection
trans
cmdType
cmdText
commandParameters);
int val = cmd
ExecuteNonQuery();
cmd
Parameters
Clear();
return val;
}
/**//// <summary>
/// 執行一條返回結果集的SqlCommand命令
通過專用的連接字符串
/// 使用參數數組提供參數
/// </summary>
/// <remarks>
/// 使用示例
/// SqlDataReader r = ExecuteReader(connString
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
connectionString
>一個有效的數據庫連接字符串</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個包含結果的SqlDataReader</returns>
public static SqlDataReader ExecuteReader(string connectionString
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(connectionString);
// 在這裡使用try/catch處理是因為如果方法出現異常
則SqlDataReader就不存在
//CommandBehavior
CloseConnection的語句就不會執行
觸發的異常由catch捕獲
//關閉數據庫連接
並通過throw再次引發捕捉到的異常
try
{
PrepareCommand(cmd
conn
null
cmdType
cmdText
commandParameters);
SqlDataReader rdr = cmd
ExecuteReader(CommandBehavior
CloseConnection);
cmd
Parameters
Clear();
return rdr;
}
catch
{
conn
Close();
throw; //編號
}
}
/**//// <summary>
/// 執行一條返回第一條記錄第一列的SqlCommand命令
通過專用的連接字符串
/// 使用參數數組提供參數
/// </summary>
/// <remarks>
/// 使用示例
/// Object obj = ExecuteScalar(connString
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
connectionString
>一個有效的數據庫連接字符串</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個object類型的數據
可以通過 Convert
To{Type}方法轉換類型</returns>
public static object ExecuteScalar(string connectionString
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
using (SqlConnection connection = new SqlConnection(connectionString))
{
PrepareCommand(cmd
connection
null
cmdType
cmdText
commandParameters);
object val = cmd
ExecuteScalar();
cmd
Parameters
Clear();
return val;
}
}
/**//// <summary>
/// 執行一條返回第一條記錄第一列的SqlCommand命令
通過已經存在的數據庫連接
/// 使用參數數組提供參數
/// </summary>
/// <remarks>
/// 使用示例
/// Object obj = ExecuteScalar(connString
CommandType
StoredProcedure
///
PublishOrders
new SqlParameter(
@prodid
));
/// </remarks>
/// <param name=
conn
>一個已經存在的數據庫連接</param>
/// <param name=
commandType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
)
/// </param>
/// <param name=
commandText
>存儲過程的名字或者 T
SQL 語句</param>
/// <param name=
commandParameters
>以數組形式提供SqlCommand命令中用到的參數列表
/// </param>
/// <returns>返回一個object類型的數據
可以通過 Convert
To{Type}方法轉換類型
/// </returns>
public static object ExecuteScalar(SqlConnection connection
CommandType cmdType
string cmdText
params SqlParameter[] commandParameters)
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd
connection
null
cmdType
cmdText
commandParameters);
object val = cmd
ExecuteScalar();
cmd
Parameters
Clear();
return val;
}
/**//// <summary>
/// 緩存參數數組
/// </summary>
/// <param name=
cacheKey
>參數緩存的鍵值</param>
/// <param name=
cmdParms
>被緩存的參數列表</param>
public static void CacheParameters(string cacheKey
params SqlParameter[] commandParameters)
{
//編號
parmCache[cacheKey] = commandParameters;
}
/**//// <summary>
/// 獲取被緩存的參數
/// </summary>
/// <param name=
cacheKey
>用於查找參數的KEY值</param>
/// <returns>返回緩存的參數數組</returns>
public static SqlParameter[] GetCachedParameters(string cacheKey)
{
SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
//新建一個參數的克隆列表
SqlParameter[] clonedParms = new SqlParameter[cachedParms
Length];
//通過循環為克隆參數列表賦值
for (int i =
j = cachedParms
Length; i < j; i++)
//使用clone方法復制參數列表中的參數
//編號
clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i])
Clone();
return clonedParms;
}
/**//// <summary>
/// 為執行命令准備參數
/// </summary>
/// <param name=
cmd
>SqlCommand 命令</param>
/// <param name=
conn
>已經存在的數據庫連接</param>
/// <param name=
trans
>數據庫事物處理</param>
/// <param name=
cmdType
>SqlCommand命令類型 (存儲過程
T
SQL語句
等等
) </param>
/// <param name=
cmdText
>Command text
T
SQL語句 例如 Select * from
/// Products</param>
/// <param name=
cmdParms
>返回帶參數的命令</param>
//編號
private static void PrepareCommand(SqlCommand cmd
SqlConnection conn
SqlTransaction trans
CommandType cmdType
string cmdText
SqlParameter[]
cmdParms)
{
//判斷數據庫連接狀態
if (conn
State != ConnectionState
Open)
conn
Open();
cmd
Connection = conn;
cmd
CommandText = cmdText;
//判斷是否需要事物處理
if (trans != null)
cmd
Transaction = trans;
cmd
CommandType = cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd
Parameters
Add(parm);
}
}
}
代碼是一個比較完整的數據訪問組件下面分析這些代碼的具體實現
()Using關鍵字見代碼編號Using處理對命名空間的引用通常如果系統提示找不到某個類一定要仔細檢查是否引用了這個類的命名空間在C# 中Using還可以實現命名空間的別名例如Using sc =SystemCollections別名就是用來簡化命名空間的別名的使用語句是sc::ArrayList list=new sc::Arraylist( )
()注釋見代碼編號在方法上面一行如果輸入///系統會自動將此方法的注釋架構搭建好主要包括Summary和param name如果方法有返回值還包括returns如果需要特殊說明可以使用remarks標志根據這個結構可以很容易地描述清楚整個方法的組成及使用方法在注釋中使用///將來在代碼調用時會出現提示提示的內容就是所添加的注釋
()CommandType的使用見代碼編號SQL Server數據處理的兩種方法存儲過程和TSQL語句每條執行語句都有個參數CommandType這是個枚舉類型有個選項StoredProcedureTableDirect和Text它們分別表示存儲過程表和TSQL語句如果CommandType參數選擇StoredProcedure則cmdText參數就是存儲過程的名字如果CommandType是Text則cmdText是SQL語句如果CommandType是TableDirect則cmdText是表名稱
()Using語句見代碼編號在Using語句中用{}定義一個范圍在語句完成時釋放語句內使用的資源Using語句通常用在獲取數據的方法中語句的范圍是從打開數據庫連接開始到所有使用連接的資源都運行完畢後終止Using語句可以與多個對象一起使用使用Using語句的對象必須繼承IDispose接口此接口實現了Dispose方法該方法才是釋放對象資源的執行者
()參數數組見代碼編號在C#中不允許使用可選參數所以參數通常由不指定大小的數組來實現數組中參數的添加由PrepareCommand方法完成
()SQL事務處理見代碼編號事務是指一組相關聯的操作在事務處理時通常鎖住相關的表等事務處理完成後才解鎖這樣保證了數據的完整性事務一般包括個方法開始事務執行事務和事務回滾(RollBack)如果事務中的一條語句出現問題則事務回滾其他語句的執行也被取消
()throw見代碼編號再次引發捕獲的異常目的是向文本中添加異常處理信息如果要引發異常throw和catch一定要搭配使用如果catch有參數則throw也要帶參數相反亦然
()哈希表見代碼編號表示鍵/值(key/value)對的組合通過鍵值的映射來訪問哈希代碼NET中的哈希表是SystemCollections命名空間提供的一個容器英文名稱為HashTable通過key來實現快速查找key區分大小寫value存儲key對應的值通常表現為object類型當取值時要進行相應的類型轉換
()哈希表的同步包裝見代碼編號private static Hashtable parmCache = Hashtable Synchronized(new Hashtable( ))這條語句實現了哈希表的同步包裝包裝是基於線程安全的此處的哈希表是static類型的靜態變量既然是static就是一次定義全局使用所有的參數都使用這個哈希表那如何保證其他人在修改的時候不影響自己的讀取呢?以前可以使用lock的方法先鎖定表不允許他人修改讀取完畢後再解鎖現在NET提供了HashTable的Synchronized方法實現同樣的功能不需要手動加鎖直接由系統框架完成
()緩存參數列表見代碼編號緩存參數列表就是將參數信息保存在已經定義的靜態HashTable中因為HashTable是靜態的一旦定義就分配了內存地址在項目中隨時都可以使用起到了緩存數據的作用
()clone克隆見代碼編號在NET中幾乎所有繼承Collections類的集合都具有clone的方法在獲取緩存參數的方法中有下面這句代碼clonedParms[i] = (SqlParameter) ((ICloneable)cachedParms[i])Clone( )因為所有的參數都保存在一個HashTable中表中保存的只是參數的名字而參數的內容則是由不同的調用給予不同的值為了正確反映調用者的值必須克隆出一個參數列表由調用者根據功能賦予對應的值
()方法重載見代碼編號定義了兩個或多個具有相同名稱但參數不同的方法在SqlHelper中ExcuteNonQuery被重載了次通過代碼中的注釋可以很清楚地看出參數列表的不同在實際應用中根據功能環境調用相應的方法
()ConfigurationManager見代碼編號是ASPNET 中新加的一個類主要對nfig文件進行管理可以輕松獲取在nfig文件中定義的配置通常用來獲取數據庫連接字符串和個性化配置信息本例在nfig中添加了下面這行數據庫連接字符串配置
<connectionStrings >
<add name=
connstring
connectionString =
server=
;database=membercard; uid=sa; pwd=
/>
</connectionStrings>
()ExcuteNonQuery方法的返回值見代碼編號在SqlCommand的方法中ExcuteNonQuery用來執行插入更新或刪除等操作程序並不要求有任何返回值但在SqlHelper中定義此方法時返回了一個數值型數據該數據用來表示執行當前語句後數據庫中被影響的行數雖然在此定義了返回值但在程序的調用中可以不用返回值直接執行方法例如SqlHelper ExcuteNonQuery( )就是正確的不一定非要寫成 int val= SqlHelper ExcuteNonQuery( )如果程序中需要的不是int值還可以進行轉換
From:http://tw.wingwit.com/Article/program/net/201311/12489.html