ASP.NET開發(fā)中的三層開發(fā)思想指的是UI層(界面顯示層),BLL層(業(yè)務(wù)邏輯層),DAL層(數(shù)據(jù)訪問層)三層,三層之間通過函數(shù)的調(diào)用來達(dá)到降低耦合,易于系統(tǒng)維護(hù)的目的,SQLHelper助手類的主要作用在于接收并執(zhí)行來自各個數(shù)據(jù)表累傳來的sql語句或存儲過程。一般的SQLHelper類中主要包括以下幾個函數(shù)功能:
1.執(zhí)行不帶參數(shù)的增刪改方法
2.執(zhí)行帶參數(shù)的增刪改方法。
3.執(zhí)行不帶參數(shù)的查詢方法。
4.執(zhí)行帶參數(shù)的查詢方法。
作為一個程序員SQLHelper類編寫的好壞不僅影響著系統(tǒng)的可維護(hù)性的強(qiáng)弱,而且它更體現(xiàn)的是一個編程人員的職業(yè)素質(zhì)。一個程序員的成長過程中必然要經(jīng)過代碼的錘煉,代碼見證了一個編程人員的成長歷程,下面通過不同版本的SQLHelper類來向大家展示一個良好的SQLHelper助手類是怎樣煉成的:
一、初涉江湖版(A級代碼)
[csharp]
namespace dal
{
public class SQLHelper
{
/// 執(zhí)行帶參數(shù)的增刪改方法
public int ExecuteNonQuery(string sqltext,CommandType ct,SqlParameter [] paras)
{
string strconn ="server=YCH-PC;database=newssystem;uid=sa;pwd=1314517";
SqlConnection conn = new SqlConnection(strconn); //定義一個數(shù)據(jù)庫連接對象(下同)
conn.Open(); //打開數(shù)據(jù)庫連接(下同)
SqlCommand cmd = new SqlCommand(sqltext , conn ); //實(shí)例化一個命令對象(下同)
cmd.CommandType = ct; //指定命令類型(下同)
cmd.Parameters.AddRange(paras); //增加參數(shù)(下同)
int res = cmd.ExecuteNonQuery(); //執(zhí)行命令(下同)
conn .Close (); //關(guān)閉數(shù)據(jù)庫連接(下同)
return res; //返回執(zhí)行結(jié)果(下同)
}
/// 執(zhí)行不帶參數(shù)的增刪改方法
public int ExecuteNonQuery(string sqltext, CommandType ct)
{
string strconn = "server=YCH-PC;database=newssystem;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
SqlCommand cmd = new SqlCommand(sqltext, conn);
cmd.CommandType = ct;
int res = cmd.ExecuteNonQuery();
conn.Close();
return res;
}
/// 執(zhí)行不帶參數(shù)的查詢方法
public DataTable ExecuteQuery(string sqltext, CommandType ct)
{
string strconn = "server=YCH-PC;database=newssystem;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
SqlDataReader sdr ;
DataTable dt=new DataTable ();
SqlCommand cmd = new SqlCommand(sqltext, conn);
cmd.CommandType = ct;
sdr = cmd.ExecuteReader();
dt.Load(sdr);
conn.Close();
return dt ;
}
/// 執(zhí)行帶參數(shù)的查詢操作
public DataTable ExecuteQuery(string sqltext, CommandType ct, SqlParameter[] paras)
{
string strconn = "server=YCH-PC;database=newssystem;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
SqlDataReader sdr;
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand(sqltext, conn);
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
sdr = cmd.ExecuteReader();
dt.Load(sdr);
conn.Close();
return dt ;
}
}
}
二、血雨腥風(fēng)版(AA級代碼)
從上面的代碼中我們可以很明顯的看出,各個函數(shù)中數(shù)據(jù)庫連接字符串、連接對象以及數(shù)據(jù)庫連接的打開和關(guān)閉都是相同的,代碼的重復(fù)往往是糟糕代碼的標(biāo)志,下面我們就通過代碼改造來減少代碼冗余,提高代碼的復(fù)用率。代碼的主要改動部分就是針對上述相同的代碼片段進(jìn)行的:
[csharp]
namespace dal
{
public class SQLHelper
{
private SqlConnection conn = null;
private SqlCommand cmd = null;
/// 實(shí)例化SQLHelper類的時候便實(shí)例化一個數(shù)據(jù)庫連接
public SQLHelper()
{
string connStr = "server=YCH-PC;database=newssystem;uid=sa;pwd=123456";
conn = new SqlConnection(connStr);
}
/// 打開數(shù)據(jù)庫連接
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
/// 關(guān)閉數(shù)據(jù)庫連接
private void OutConn()
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
/// 執(zhí)行不帶參數(shù)的增刪改操作
public int ExecuteNonQuery(string cmdText, CommandType ct)
{
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
int res = cmd.ExecuteNonQuery();
OutConn();
return res;
}
/// 執(zhí)行帶參數(shù)的增刪改方法
public int ExecuteNonQuery(string sqltext, CommandType ct, SqlParameter[] paras)
{
SqlCommand cmd = new SqlCommand(sqltext, GetConn());
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
int res = cmd.ExecuteNonQuery();
OutConn();
return res;
}
/// 執(zhí)行不帶參數(shù)的查詢方法
public DataTable ExecuteQuery(string sqltext, CommandType ct)
{
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand(sqltext, GetConn());
cmd.CommandType = ct;
SqlDataReader sdr = cmd.ExecuteReader();
dt.Load(sdr);
sdr.Close();
OutConn();
return dt;
}
/// 執(zhí)行帶參數(shù)的查詢操作
public DataTable ExecuteQuery(string sqltext, CommandType ct, SqlParameter[] paras)
{
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand(sqltext, GetConn());
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
SqlDataReader sdr = cmd.ExecuteReader();
dt.Load(sdr);
sdr.Close();
OutConn();
return dt ;
}
}
}
三、爐火純青版(AAA級代碼)
通過”瘦身行動“,現(xiàn)在的代碼是不是比第一版代碼清晰了很多呢?但這還不是最后的結(jié)果。有的人會提出這樣的問題:把連接字符串寫在SQLHelper類中,如果我現(xiàn)在要更換數(shù)據(jù)庫,那豈不是要對SQLHelper助手類進(jìn)行更改,這樣似乎不符合我們”開放擴(kuò)展,關(guān)閉修改“的要求。另外在執(zhí)行查詢過程時需要先關(guān)閉SqlDataReader再關(guān)閉數(shù)據(jù)庫連接,這樣在代碼中也出現(xiàn)了重復(fù),能不能再進(jìn)一步對代碼進(jìn)行改造來解決這兩個問題呢?下面我們就上述兩個問題對代碼進(jìn)行進(jìn)一的步改造: 解決更換數(shù)據(jù)庫的問題我們采取的方法是將連接字符串寫在配置文件中,具體步驟為:
1. 雙擊web層中Web.config文件,配置文件中的相關(guān)內(nèi)容將會出現(xiàn)。
2. 找到<connectionStrings>和</connectionStrings>,在二者之間添加如下內(nèi)容:<add name=<add name=連接字符串 connectionString ="server=YCH-PC;database=newssystem;uid=sa;pwd=具體的登陸密碼"/>
3. 修改SQLHelper類中的相關(guān)代碼如下:
[csharp]
namespace dal
{
public class SQLHelper
{
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;
public SQLHelper()
{
string strconn = ConfigurationManager.ConnectionStrings["strconn"].ConnectionString;
conn = new SqlConnection(strconn );
}
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
//關(guān)閉數(shù)據(jù)庫連接
private void OutConn()
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
/// 執(zhí)行不帶參數(shù)的增刪改SQL語句或存儲過程
public int ExecuteNonQuery(string cmdText, CommandType ct)
{
int res;
try
{
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
res = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
OutConn();
}
return res;
}
/// 執(zhí)行帶參數(shù)的增刪改SQL語句或存儲過程
public int ExecuteNonQuery(string cmdText, SqlParameter[] paras, CommandType ct)
{
int res;
try
{
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
res = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
OutConn();
}
return res;
}
/// 執(zhí)行不帶參數(shù)的查詢SQL語句或存儲過程
public DataTable ExecuteQuery(string cmdText, CommandType ct)
{
DataTable dt = new DataTable();
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(sdr);
}
return dt;
}
/// 執(zhí)行帶參數(shù)的查詢SQL語句或存儲過程
public DataTable ExecuteQuery(string cmdText, SqlParameter[] paras, CommandType ct)
{
DataTable dt = new DataTable();
cmd = new SqlCommand(cmdText, GetConn());
cmd.CommandType = ct;
cmd.Parameters.AddRange(paras);
using (sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(sdr);
}
return dt;
}
}
}
經(jīng)過對代碼的再次改造,不但代碼的重復(fù)率大大降低,而且如需更換數(shù)據(jù)庫,只要在配置文件中更改相應(yīng)的連接字符串就可完。在編寫查詢(包括帶參數(shù)的和不帶參數(shù)的查詢方法)方法時,用using方法,在關(guān)閉SqlDataReader對象的時候同時關(guān)閉與之相關(guān)聯(lián)的數(shù)據(jù)庫連接,避免了try catch語句的使用,代碼更加簡潔。經(jīng)過三次改造,SQLHelper助手類的變身就此完成。