不管什么項目基本都不能避免對頻繁的對數據庫進行操作。如果直接在代碼中操作,不僅會導致代碼里面夾雜着太多的SQL語句,影響代碼的可讀性,還會因為創建太多變量影響程序運行性能。基於MVC編程思想,對數據庫的操作應該與控制邏輯的代碼分離。
這時我們可以把相對應的,需要大量重復使用的代碼封裝到一個幫助類里--數據庫幫助類。在這個類里,我們只需要實例化一次SqlConnection,就可以在程序關閉前重復使用該類里面的所有方法。
/// <summary> /// 數據庫幫助類 /// </summary> public class SqlHelpClass { static private string strServer;//數據庫服務器地址,就是計算機名稱 static private string strUid;//SQLserver用戶名稱 static private string strPwd;//密碼 static private string strDatabaseName;//數據庫名稱 //屬性限制外部只能設置數據庫的鏈接信息 static public string StrServer { set => strServer = value; } static public string StrUid { set => strUid = value; } static public string StrPwd { set => strPwd = value; } static public string StrDatabaseName { set => strDatabaseName = value; } static public string strSql { //這個字符串是連接字符串,包含着數據庫的信息,對外部只提供信息不能修改 get { return strServer + ";" + strUid + ";" + strPwd + ";" + strDatabaseName; } } static SqlConnection sqlConnection; static SqlCommand cmd; static SqlHelpClass() { //靜態構造函數,如果你需要給數據庫信息設置默認值 strServer = ""; strUid = ""; strPwd = ""; strDatabaseName = ""; } /// <summary> /// 返回一個數據庫連接 /// </summary> /// <returns></returns> public static SqlConnection GetSqlConnection() { sqlConnection = new SqlConnection(); sqlConnection.ConnectionString = strSql; return sqlConnection; } #region 對連接執行SQL語句或存儲過程並返回受影響行數 /// <summary> /// 對連接執行SQL語句並返回受影響行數 /// </summary> /// <param name="sql">數據庫操作命令語句</param> /// <returns>受影響的行數</returns> private static int ExecuteNonQueryTypeText(string sql) { sqlConnection = new SqlConnection();//創建一個數據庫連接實例(實例就是對象) //對這個類SqlConnection作用不明白的可以把鼠標放到類名可以顯示微軟對類給出的說明 try { sqlConnection.ConnectionString = strSql;//數據庫的信息給到這個連接, sqlConnection.Open();//打開連接 cmd = new SqlCommand();/*創建一個查詢實例 *SqlConnection就像路,我們創建SqlConnection實例時就打通了連通數據庫的一條路 *SqlCommand就是信使, *我們每次要對數據庫發出指令時,SqlCommand對象就可以幫我們把這個指令送到數據庫 * 數據庫處理完后,再通過SqlCommand把我們需要的數據傳回來。*/ cmd.CommandText = sql;//設置要執行的數據庫命令,就是你得把信給信使 cmd.Connection = sqlConnection;//設置查詢 return cmd.ExecuteNonQuery();//返回受影響的行數,cmd.ExecuteNonQuery()在這里相當於執行命令:你給我把信送過去。 //如果沒有cmd.ExecuteNonQuery(),那么命令是不會執行的。 } catch (Exception e) { throw e;//拋出異常 //如果不想拋出異常影響程序進行,這里可以不寫 //或者返回個-1,然后在使用類里做判斷 } finally { sqlConnection.Close();//關閉數據庫連接 //數據庫連接一般都是一次查詢打開一個連接,查詢結束關閉當前連接。 //都已經把主要代碼寫在幫助類里了就不要想着強行省代碼,該寫的還得寫 //不要想着一個SqlConnection多次共用,防止出現不必要的異常或錯誤 } } /// <summary> /// 對連接執行有參數的數據庫的存儲過程並返回受影響行數 /// </summary> /// <param name="StoredProcedureName">數據庫的存儲過程的名稱</param> /// <param name="sqlParameters">SqlParameter集合</param> /// <returns>受影響行數</returns> private static int ExecuteNonQueryTypeStoredProcedure(string StoredProcedureName, SqlParameter[] sqlParameters) { /*SqlParameter: *例: SqlParameter("@ID",ID) * @ID:就是數據庫存儲過程的參數 * ID:就是你給這個參數賦的值 * * 要執行存儲過程,首先就要給存儲過程里邊的參數賦值, * 一個SqlParameter可以給一個參數賦值, * 而一個SqlParameter數組可以包含給所有參數賦值的SqlParameter */ sqlConnection = new SqlConnection(); try { sqlConnection.ConnectionString = strSql;//數據庫的信息給到這個連接, sqlConnection.Open();//打開連接 cmd = new SqlCommand();//創建一個查詢實例 cmd.CommandType = CommandType.StoredProcedure;//設置cmd的行為類型 cmd.CommandText = StoredProcedureName;//設置要執行的數據庫存儲過程的名稱 cmd.Connection = sqlConnection;//設置連接 cmd.Parameters.AddRange(sqlParameters);//AddRange方法給cmd的參數添加sqlParameters集合 return cmd.ExecuteNonQuery();//返回結果 } catch (Exception e) { throw e;//拋出異常 } finally { sqlConnection.Close();//關閉數據庫連接 } } /// <summary> /// 連接執行無參數的數據庫的存儲過程並返回受影響行數 /// </summary> /// <param name="StoredProcedureName">數據庫的存儲過程的名稱</param> /// <returns>受影響行數</returns> private static int ExecuteNonQueryTypeStoredProcedure(string StoredProcedureName) { sqlConnection = new SqlConnection(); try { sqlConnection.ConnectionString = strSql;//數據庫的信息給到這個連接, sqlConnection.Open();//打開連接 cmd = new SqlCommand();//創建一個查詢實例 cmd.CommandType = CommandType.StoredProcedure;//設置cmd的行為類型 cmd.CommandText = StoredProcedureName;//設置要執行的數據庫存儲過程的名稱 cmd.Connection = sqlConnection;//設置連接 return cmd.ExecuteNonQuery();//返回結果 } catch (Exception e) { throw e;//拋出異常 } finally { sqlConnection.Close();//關閉數據庫連接 } } /// <summary> /// 對連接執行SQL語句或無參數存儲過程並返回受影響行數 /// </summary> /// <param name="sqlOrSPname">SQL語句或者無參數存儲過程名稱</param> /// <param name="commandType">解釋命令字符串類型</param> /// <returns></returns> public static int ExecuteNonQuery(string sqlOrSPname, CommandType commandType) { switch (commandType) { case CommandType.StoredProcedure: return ExecuteNonQueryTypeStoredProcedure(sqlOrSPname); case CommandType.Text: return ExecuteNonQueryTypeText(sqlOrSPname); default: return ExecuteNonQueryTypeText("select * from "+ sqlOrSPname); } } /// <summary> /// 連接執行有參數存儲過程並返回受影響行數 /// </summary> /// <param name="sqlOrSPname">有參數存儲過程名稱</param> /// <param name="sqlParameters">SqlParametes數組</param> /// <returns></returns> public static int ExecuteNonQuery(string sqlOrSPname, SqlParameter[] sqlParameters) { return ExecuteNonQueryTypeStoredProcedure(sqlOrSPname, sqlParameters); } #endregion /// <summary> /// 返回查詢結果集的第一行第一列的值 /// </summary> /// <returns>查詢結果第一行第一列的值</returns> public static object ExecuteScalar(string sql) { sqlConnection = new SqlConnection(); try { sqlConnection.ConnectionString = strSql;//數據庫的信息給到這個連接, sqlConnection.Open();//打開連接 cmd = new SqlCommand();//創建一個查詢實例 cmd.CommandText = sql.ToString();//設置要執行的數據庫命令 cmd.Connection = sqlConnection;//設置查詢 return cmd.ExecuteScalar();//返回結果 } catch (Exception e) { throw e;//拋出異常 } finally { sqlConnection.Close();//關閉數據庫連接 } } #region 查詢數據庫返回一個DataTable /// <summary> /// 查詢數據庫表返回一個只讀結果集 /// </summary> /// <param name="sql">查詢語句</param> /// <returns>DataTable</returns> public DataTable GetReadOnlyDataTable(string sql) { sqlConnection = new SqlConnection(); try { sqlConnection.ConnectionString = strSql; cmd = new SqlCommand(sql, sqlConnection);//利用SqlCommand構造函數的重載,可以在實例化時就給相對應得屬性賦值 SqlDataReader reader = cmd.ExecuteReader();//根據sql讀取數據庫表,返回一個只讀結果集 DataTable dt = new DataTable();//創建一個DataTable對象 dt.Load(reader);//將讀到的結果集填充到DataTable對象 return dt; } catch (Exception e) { throw e;//拋出異常 } finally { sqlConnection.Close();//關閉數據庫連接 } } /// <summary> /// 查詢數據庫表返回一個可讀寫可操作的結果集 /// </summary> /// <param name="sql"></param> /// <returns></returns> public DataTable GetReadWwriteDataTable(string sql) { sqlConnection = new SqlConnection(); try { sqlConnection.ConnectionString = strSql; SqlDataAdapter adapter =new SqlDataAdapter(sql, sqlConnection);//返回一個可讀寫可操作的結果集 DataTable dt = new DataTable();//創建一個DataTable對象 adapter.Fill(dt);//將結果集填充到DataTable對象 return dt; } catch (Exception e) { throw e;//拋出異常 } finally { sqlConnection.Close();//關閉數據庫連接 } } #endregion }
靜態構造函數:初始化類的靜態數據成員
僅在類被加載時執行一次
不允許使用訪問修飾符
寫在靜態構造函數里,只要在其他類里出現SqlHelpClass,數據庫幫助類類名,那么SqlHelpClass就算被加載了,不需要實例化就創建好了對數據庫的連接。而里面的方法都是靜態方法,全部都可以類名點方法名(例:SqlHelpClass.ExecuteNonQuery())就可以實用,重頭到尾都不需要實例化SqlHelpClass。
可以在靜態構造函數里給字段賦默認值。
還有一點要注意的是:sqlconnection對象一般都是當次使用,使用完然后關閉。