標籤:
現在對資料庫(以MySql為例)的操作大多會封裝成一個類,如下例所示:
1 namespace TESTDATABASE 2 { 3 public enum DBStatusCode { ALL_OK, MySqlExcuteErr } 4 public class TestDB 5 { 6 private string hostIp; 7 private string dbName; 8 private string dbUser; 9 private string dbPasswd;10 private MySqlConnection dbConn;11 12 public TestDB() 13 {14 this.initConn();15 }16 ~TestDB()17 {18 dbConn.Dispose();19 }20 void initConn()21 {22 dbName = "testDB";23 hostIp = "127.0.0.1";24 dbUser = "root";25 dbPasswd = "root";26 string connString; // Connection string。資料庫連接字串大全:http://www.connectionstrings.com/27 connString = "SERVER=" + hostIp + ";" + "DATABASE=" +28 dbName + ";" + "UID=" + dbUser + ";" + "PASSWORD=" + dbPasswd + ";";29 dbConn = new MySqlConnection(connString);30 }31 // Open connection32 public void openConn()33 {34 if (dbConn.State == ConnectionState.Closed)35 dbConn.Open();36 }37 // Close connection38 public void closeConn()39 {40 if (dbConn.State == ConnectionState.Open)41 dbConn.Dispose();42 }43 // Insert44 public DBStatusCode insertTest(ItermList itemList)45 {46 DBStatusCode flag = DBStatusCode.ALL_OK;47 openConn();48 string cmdText = "insert into testTable (c1, c2, c3, c4)"49 + "VALUES (@c1, @c2, @c3, @c4)";50 MySqlCommand cmd = new MySqlCommand(cmdText, dbConn);51 try52 {53 foreach (Item item in itemList)54 {55 cmd.Parameters.Clear(); // it is needed56 cmd.Parameters.AddWithValue("@c1", item.c1);57 cmd.Parameters.AddWithValue("@c2", item.c2);58 cmd.Parameters.AddWithValue("@c3", item.c3);59 cmd.Parameters.AddWithValue("@c4", item.c4);60 cmd.ExecuteNonQuery();61 }62 }63 catch (Exception ex)64 {65 flag = DBStatusCode.MySqlExcuteErr;66 }67 finally68 {69 cmd.Dispose();70 }71 closeConn();72 return flag;73 }74 }75 }
上邊例子涉及到對MySql資料庫的資料匯入。可以看出(56~60),每迴圈一次,就會對資料庫插入一次。當資料量比較小時,可能還看不出軟體的卡頓現象;當資料量很大時,整個軟體可能就會卡住幾分鐘了。所以,我們最好是當所有資料都準備好時,再一次性向資料庫定入,以減少插入次數,以最終減少資料匯入時間。而且,我們還想,在資料庫插入失敗的情況下還能夠復原。下邊是改進的函數:
1 // Insert 2 public DBStatusCode insertTest(ItermList itemList) 3 { 4 DBStatusCode flag = DBStatusCode.ALL_OK; 5 openConn(); 6 string cmdText = "insert into testTable (c1, c2, c3, c4)" 7 + "VALUES (@c1, @c2, @c3, @c4)"; 8 MySqlCommand cmd = new MySqlCommand(cmdText, dbConn); 9 MySqlTransaction tx = this.dbConn.BeginTransaction();10 cmd.Transaction = tx;11 try12 {13 foreach (Item item in itemList)14 {15 cmd.Parameters.Clear(); // it is needed16 cmd.Parameters.AddWithValue("@c1", item.c1);17 cmd.Parameters.AddWithValue("@c2", item.c2);18 cmd.Parameters.AddWithValue("@c3", item.c3);19 cmd.Parameters.AddWithValue("@c4", item.c4);20 cmd.ExecuteNonQuery();21 }22 tx.Commit();23 }24 catch (Exception ex)25 {26 flag = DBStatusCode.MySqlExcuteErr;27 tx.Rollback();28 }29 finally30 {31 cmd.Dispose();32 }33 closeConn();34 return flag;35 }
這裡的改進可以說還只是初步的。當資料特別大時,這種方法就會出問題了。因為電腦要一次性把非常多的資料插入到資料庫,有可能因為記憶體不足等原因而導致最終匯入時間過長等。所以,在有一些情況下,我們還得分批提交(tx.Commit()),例如每1000個資料提交一次,這樣就能夠大大減輕電腦和資料庫負擔了。
關於MySql事務介紹資料:
MySQL 事務
說說MySQL中的事務
關於批量插入資料,可參考的資源還有:
MySQL大量資料插入各種方法效能分析與比較
在C#中完成海量資料的批量插入和更新
[C#][SQL SERVER] 提高 Insert 效能
.NET 批量插入資料,DataSet, SqlDataAdapter.Update
datatable 使用SqlDataAdapter.Update批量插入更新資料
"C#":MySql批量數量匯入