作為第一個完整的、簡單的.NET項目,我很高興在一個月之內完成人事系統的初級探秘。跟隨著楊中科老師的腳步進行對數據庫.net的學習。下面我就對整個系統所用到的知識進行簡單的總結,如有不對歡迎批評指正:
(一)關于三層架構的介紹:
在開發人事管理系統時候我們進行了三層架構的搭建工作,在vs的項目依賴圖如圖所示:
BLL將USL與DAL隔開了,并且加入了業務規則(文獻來自:http://www.49028c.com/gaoweipeng/archive/2009/01/18/1377855.html)
在“數據訪問層”中,最好不要出現任何“業務邏輯”!也就是說,要保證“數據訪問層”的中的函數功能的原子性!即最小性和不可再分。“數據訪問層”只管負責存儲或讀取數據就可以了。
但是在我們的這個項目當中,因為BLL層使用的次數非常少,所以可能我們將BLL層的東西寫入到了USL層當中去,這樣我們做了一個簡化的三層架構,并填入了MODEL層進行串聯。
(二)ADO.NET簡單梳理(文獻來自:ADO.NET——全面梳理)
2.1 sqlConnection連接對象:
2.1.1.連接字符串
基本語法:數據源(Data Source)+數據庫名稱(Initial Catalog)+用戶名(User ID)+密碼(PassWord)(這種方式比較安全)!
推薦文章 :SQL Server 連接字符串和身份驗證,你必須知道的ADO.NET(三) 連接字符串,你小覷了嗎?,SQL Server 2008連接字符串寫法大全,連接字符串有很多的寫法,最保險的寫法可以借助“SqlConnectionStringBuilder”類,它提供了全面的連接字符串的屬性,以至于減少出錯率(相關屬性查MSDN),還有大多數連接字符串都寫在配置文件里面了!
2.1.2.創建連接對象
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder() { DataSource = "", InitialCatalog = "", UserID = "", Password = "" };SqlConnection connection = new SqlConnection(connectionStringBuilder.ToString());
當然我們可以選擇在config里面進行對鏈接對象的配置:
<connectionStrings> <add name="dbConnStr" connectionString ="Data Source=.;Initial Catalog=;User ID=;Password="/> </connectionStrings>
然后再利用代碼進行連接:
PRivate static string connStr = ConfigurationManager.ConnectionStrings["dbConnStr"].ConnectionString;
2.1.3.打開和關閉連接對象(使用Using來關閉連接)
using(SqlConnection connection = new SqlConnection(connectionStringBuilder.ToString())) { connection.Open(); connection.Close(); }
2.2 SqlCommand(命令對象)
2.2.1.實例化的時候默認初始化的四個屬性
2.2.2.創建命令對象
使用連接對象的“CreateCommand()”方法創建命令對象,也可以使用new來實例化對象!
1 SqlCommand command = connection.CreateCommand(); //這種方式比較好,也可以自己實例化一個對象!
2.2.3.幾個重要屬性
①CommandText:獲取或設置要對數據源執行的 Transact-SQL 語句、表名或存儲過程!
?、贑ommandType:設置你執行的SQL語句是存儲過程還是T-SQL(是一個枚舉)!
?、跴arameters:設置你T-SQL中你需要用到的參數(后面會講到),是一個“SqlParametersCollection”類型,這個屬性很重要,是你通過代碼給SQL語句傳遞參數的途徑,所以記住語法,記住一些使用規則講對編碼有很大的幫助!
2.2.4.幾個重要的方法(相信大家熟悉的不能再熟悉了)
?、貳xecuteNonQuery:返回是影響的行數(int),主要執行更新,添加,刪除等操作!
?、贓xecuteReader:執行SQL或存儲過程,返回的是SqlDataReader類型,主要用來查詢!
★ 這邊注意這個方法的重載 CommandBehaviour 枚舉,成員如下:
1 command.ExecuteReader(CommandBehavior.CloseConnection); //在執行讀取之后會自動關閉連接對象
③ExecuteScalar:返回執行結果集中的第一行第一列,如果沒有數據,則返回NULL!
Note:因為可能會返回“Null”值,所以需要對結果進行判斷,如下:
1 object my = cmd.ExecuteScalar();2 if (object.Equals(my,null)) //可以使用Equals進行Null值的判斷,易讀性強3 Console.WriteLine("Not Data");4 else5 Console.WriteLine("Yes");
④CreateParameter:創建SqlParameter實例
1 SqlParameter para = cmd.CreateParameter() //此方法適合SQL語句中只有一個參數的情況!
推薦文章:你必須知道的ADO.NET(六) 談談Command對象與數據檢索
你必須知道的ADO.NET(七) Wow!Command對象高級應用
2.3 SqlParameter(Sql參數)-----如果沒有這個就會產生sql漏洞注入攻擊
2.3.1.幾個重要的屬性
ParameterName: 設置參數名
Value: 給參數設置值
Size: 設置參數字節最大大小(以字節為但為)
SqlDbType: 參數在SQL中的類型
1 SqlParameter paras = new SqlParameter()2 {3 ParameterName = "@name",4 Value = 10,5 SqlDbType = SqlDbType.Int,6 Size = 47 };
2.3.2.命令對象添加參數集合的幾種方法
?、貯ddWithValue
②Add
?、跘ddRange
推薦文章:SqlParameter的作用與用法,代碼如下:
1 using (SqlConnection connection = new SqlConnection("")) 2 { 3 SqlCommand command = connection.CreateCommand(); 4 command.CommandText = ""; 5 6 //可以使用這種方式添加多個參數,不過方式不夠好 7 command.Parameters.Add("@name", SqlDbType.NVarChar).Value = "yang"; //第一種方式 8 command.Parameters.Add("@age", SqlDbType.Int).Value = 888; 9 command.Parameters.Add("@address", SqlDbType.NVarChar, 100).Value = "Jiang Su";10 11 //這種方式直接給定參數名和參數就可以了,可操作性比較差12 command.Parameters.AddWithValue("@name", "yang");13 command.Parameters.AddWithValue("@age", 888).SqlDbType = SqlDbType.Int;14 command.Parameters.AddWithValue("@address", "Jiang su").SqlDbType = SqlDbType.NVarChar;15 16 //直接使用參數集合添加你需要的參數,推薦這種寫法17 SqlParameter[] parameters = new SqlParameter[]18 {19 new SqlParameter("@name",SqlDbType.NVarChar,100){Value = "yang"},20 new SqlParameter("@age",SqlDbType.Int,2){Value = 888},21 new SqlParameter("@address",SqlDbType.NVarChar,20){Value = "Jiang Su"}, 22 };23 command.Parameters.AddRange(parameters); //參數也可以是一個Array數組,如果采用數組參數代碼的可讀性和擴展性就不是那么好了24 25 //當我們把參數都添加好之后,會生成一個“SqlParameterCollection”集合類型,相當于參數的集合26 //那么我們就可以對這些參數進行修改和移除了27 //說穿了“SqlParameterCollection”內部其實是一個List<SqlParameter>的集合,只是它里面的復雜度比較高,考慮的很全面28 command.Parameters[0].Value = "hot girl";29 command.Parameters[0].Size = 200;30 }
2.3.3.說說“SqlParameterCollection”,參數集合
上面添加的“SqlParameter”參數都被添加到了“SqlParameterCollection”集合中去了,所以我們才能夠對它進行讀取和修改!
2.4 SqlDataAdapter(數據適配器)
2.4.1.構造函數
1 四個重載: 2 1. 無參3 2. SqlDataAdapter(SqlCommand) → 執行命令對象實例4 3. SqlDataAdapter(String, SqlConnection) → ①只能指定查詢語句 ②連接對象實例5 4. SqlDataAdapter(String, ConnectionString) → 用 SelectCommand 和一個連接字符串初始化 SqlDataAdapter 類的一個新實例6 Note:第四個重載就把連接對象和命令對象都包含進去了!
2.4.2.填充數據(Fill)
最簡單的填充數據
1 DataSet dataSet = new DataSet();2 using (SqlConnection conn = new SqlConnection(""))3 {4 conn.Open();5 SqlCommand command = conn.CreateCommand();6 command.CommandText = "select name,age,address from MyInformation";7 SqlDataAdapter dataAdapter = new SqlDataAdapter(command);8 dataAdapter.Fill(dataSet); //填充數據9 }
2.4.3.使用“SqlCommandBuilder”對數據進行增刪改查
①添加數據
1 using (SqlConnection conn = new SqlConnection(ConnectionString())) 2 { 3 conn.Open(); 4 //構建查詢語句,也可以指定SqlCommand,其中變換的方法有很多 5 SqlDataAdapter da = new SqlDataAdapter("select LastName,FirstName from dbo.Employees", conn); 6 DataSet ds = new DataSet(); 7 da.Fill(ds); 8 //這句話很重要,它會把你在DataSet增加的數據轉化為SQL語句用來更新數據庫 9 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);10 //添加行,實例化一個行對象,注意是用NewRow來創建行11 DataRow row = ds.Tables[0].NewRow();12 row[0] = "Yang";13 row[1] = "鬼頭";14 ds.Tables[0].Rows.Add(row); //添加到表中15 da.Update(ds); //把DataSet中表和數據庫進行對比,更新16 }
?、谛薷臄祿?/p>
1 using (SqlConnection conn = new SqlConnection("")) 2 { 3 SqlDataAdapter da = new SqlDataAdapter("SQL語句或你自己定義的命令對象", conn); 4 DataSet ds = new DataSet(); 5 da.Fill(ds); 6 //很重要的一句話 7 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); 8 ds.Tables[0].Rows[12][1] = ""; //修改數據 9 da.Update(ds);10 //調用Update方法其中隱式的調用了AcceptChanges方法,更新數據集中的數據11 //如果你繼續使用這個數據集而沒有調用這個方法,在后面的使用會出現異常12 ds.AcceptChanges(); //這句話可以不寫的13 }
?、蹌h除數據
1 using (SqlConnection conn = new SqlConnection("")) 2 { 3 SqlDataAdapter da = new SqlDataAdapter("SQL語句或你自己定義的命令對象", conn); 4 DataSet ds = new DataSet(); 5 da.Fill(ds); 6 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); 7 //刪除數據 8 ds.Tables[0].Rows[12].Delete(); 9 da.Update(ds); //這邊會隱式調用DataTable的AcceptChanges方法10 }
Note(很重要的注意點):值得注意的是Update方法已經隱式幫我調用了AcceptChanges,不比擔心狀態為改變刪除數據會報錯,微軟已經幫我們都做好了,其實背后就是做的Table.AcceptChanges()這件事,如果在一般的DataTable中會怎么樣,提交自上次調用 AcceptChanges 以來對該行進行的所有更改,在調用這個方法之后,表中所有更改將會提交,所有行狀態(RowState)狀態都將變為Unchanged,在DataSet中我將會說到這些內容!
2.4.4.關于“SqlDataAdapter”中Fill方法的一些討論
簡單的寫一下,MSDN上都有的,查一下就知道了!
1 ★指定填充數據的數量,如:4 //應該是從第六行開始,后面的十條記錄5 da.Fill(ds,5,10,”MyTable”)
2.5 DataSet,DataTable,DataRow,DataColumn
表示數據存放在緩存中,DataSet里面可以包含多個DataTable,DataTable中有多個DataColumn和多個DataRow,包括對各種對DataTable的操作,以及對列和行的操作,在進行DataSet,DataTable進行操作的時候,應該先判斷它們是否為Null,這是最基本的!
1.DataTable,DataRow,DataColumn
?、賱摻ㄗ约旱腄ataTable :
1 DataTable dt = new DataTable("Table"); 2 DataColumn columnName = new DataColumn(); 3 columnName.ColumnName = "Name"; 4 //columnName.DataType = typeof(string); 5 //注意和上面一句話的比較 6 columnName.DataType = Type.GetType("System.String"); 7 columnName.DefaultValue = "YangCaoGui"; 8 dt.Columns.Add(columnName); //DataColumnCollection的集合 9 DataRow row = dt.NewRow(); //使用NewRow方法來實例化一個行10 row[columnName] = "WangWei"; //采用索引的方式有很多11 dt.Rows.Add(row); //DataRowCollection的集合12 Console.WriteLine("Type: " + dt.Columns[0].DataType.Name);
?、谑褂脤ο蠹铣跏蓟骱喕a,以及使用“DataColumnCollection”和“DataRowCollection”來操作已添加的行和列
構造函數的訪問修飾符為Internal,通過這兩個集合可以對Column和Row進行“增,刪,改,查”,詳細見MSDN,如Remove,Add,RemoveAt etc!
1 dt.Columns.Add(new DataColumn("Age", typeof(Int32))); 2 dt.Columns.Add(new DataColumn() 3 { 4 ColumnName = "Address", 5 DataType = typeof(string), 6 DefaultValue = "江蘇海安" 7 }); 8 //我們這邊使用Add的方法的第二個重載 9 dt.Rows.Add(new object[] {"11", 44, "222", "yang cao gui"});10 //我們也可以對添加好的行和列進行讀取和修改11 dt.Columns[0].ColumnName = "wang wei";12 dt.Rows[0]["wang wei"] = "我把這行這列的值修改了,哈哈";
③使用表達樹快速構建自己的列,詳細的也可以查MSDN
public static void DataTableExpression() { DataTable dt = new DataTable("Table"); DataColumn price = new DataColumn("price", typeof(Int32)); DataColumn number = new DataColumn("number", typeof(Int32)); dt.Columns.Add(price); dt.Columns.Add(number); for (int i = 1; i <= 5; i++) { DataRow newRow = dt.NewRo(); newRow["price"] = i; newRow["number"] = i + 5; dt.Rows.Add(newRow); } //顯示表數據 for (int i = 0; i < dt.Rows.Count; i++) { Console.WriteLine("Price: {0} , Number:{1}", dt.Rows[i]["price"], dt.Rows[i]["number"]); } //使用Expression來定制自己的Table Console.WriteLine("-----------------------------------"); DataColumn total = new DataColumn("total", typeof(Int32)); dt.Columns.Add(total); //可以使用這樣的方式來定制自己DataTable dt.Columns["total"].Expression = "price * number"; //顯示定制后的數據 Console.WriteLine("顯示數據"); for (int i = 0; i < dt.Rows.Count; i++) { Console.WriteLine("Price: {0} , Number:{1} ,Total:{2}", dt.Rows[i]["price"], dt.Rows[i]["number"], dt.Rows[i]["total"]); } }
下次收藏一些sqlhelper的封裝數據庫操作類(這才是精華)
下面是一些鏈接的推薦環節:
只有充分理解了上面的知識,才能更好的封裝,才能寫出健壯的面向對象數據庫操作類庫,因本人知識有限,簡單的封裝還可以,但是不足以見人,所以收集了了一些好文章,供我們來學習:
1.SqlHelper- -高懸的雙刃劍(到底好用么~~) (提煉更加健壯的代碼)
2.我的DbHelper數據操作類(自定義操作類庫)
3.JSM SqlHelper 2.0 源碼下載(封裝的更細啦,有機會研究研究)
4.微軟原版SQLHelper類(代碼太多,有很多我們會用不到,還有重載的也太多了吧!)
好了就這么多了,想簡單也很簡單,想復雜登天還難,哈哈,還是看個人的選擇把,園子里面這方面的文章也有很多,一搜一大堆,好好研究下就ok了!
新聞熱點
疑難解答