近期工做中發現批量插入的方法需求愈來愈大。因此在ORM中增長了MYSQL的批量插入方法。由三個方法組成,能夠使用在不一樣狀況下。sql
一、根據傳入的實體集合生成批量插入的SQL語名 GetInsertSqlBatch()ui
二、在方法1的基礎上增長一個執行並返回是否成功的功能 ExecuteInsertModelBatch()。orm
三、上面兩個方法都沒有控制每次批量插入的最大數量。只適用於小量批量插入狀況。若是實體集合一次性傳入1萬,10萬也作一次提交的話好像不太合適吧。因此就有了第三個方法。第三個方法是第二個方法的重載,增長了<param name="batchNum">每一個批量插入的數量</param>參數。用於控制每一個批次最大插入數量。轉入0時使用默認值爲100。當插入實體集合大於100或指定的值時,將根據設定的batchNum值的來分批提交。blog
下面是具體代碼的實現。string
/// <summary> /// 獲取批量插入SQL /// </summary> /// <param name="entitys">插入實體集合</param> /// <param name="sql">輸出SQL</param> /// <param name="tableName">表名</param> /// <param name="excludeProperties">過濾屬性名稱列表</param> /// <returns>SQL參數集合</returns> public static List<MySqlParameter> GetInsertSqlBatch<T>(List<T> entitys, out string sql, string tableName, params string[] excludeProperties) { List<MySqlParameter> sqlParameters = new List<MySqlParameter>(); sql = string.Empty; if (entitys != null && entitys.Count > 0) { var type = entitys.First().GetType(); tableName = GetTableName(type, tableName); //INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) // VALUES ('0', 'userid_0', 'content_0', 0), // ('1', 'userid_1', 'content_1', 1); if (!string.IsNullOrEmpty(tableName)) { StringBuilder InsertSql = new StringBuilder(string.Format("Insert into {0}(", tableName.ToLower())); StringBuilder ValuesSql = new StringBuilder(" Values("); var propertieList = GetProperties(type); var entityItemIndex = 1; try { //循環要插入的實體集合 foreach (var entityItem in entitys) { //循環每一個實體的屬性集合 var propertieIndex = 0; foreach (var propertieItem in propertieList.Values) { //是否添加屬性 if (ValidateIsAddPropertie(type, propertieItem, OperationType.Insert, paramsArrayToDictionary(excludeProperties))) { if (entityItemIndex == 1) { InsertSql.AppendFormat("{0},", propertieItem.Name); } var parameterName = string.Format("@{0}{1}", propertieItem.Name, entityItemIndex); if (entityItemIndex > 1 && propertieIndex == 0) { ValuesSql.Append("("); } ValuesSql.AppendFormat("{0},", parameterName); var value = propertieItem.GetValue(entityItem); sqlParameters.Add(new MySqlParameter(parameterName, value ?? string.Empty)); } if (propertieIndex == propertieList.Count - 1) { if (entityItemIndex == 1) { InsertSql.Remove(InsertSql.Length - 1, 1); InsertSql.Append(")"); } ValuesSql.Remove(ValuesSql.Length - 1, 1); ValuesSql.Append("),"); } propertieIndex++; } entityItemIndex++; } } catch (Exception ex) { if (sqlParameters != null && sqlParameters.Count > 0) { sqlParameters.Clear(); sqlParameters = null; } throw ex; } sql = string.Format("{0};", InsertSql.Append(ValuesSql).ToString().Trim(',')); InsertSql.Clear(); ValuesSql.Clear(); } } return sqlParameters; } /// <summary> /// 執行批量插入實體方法 /// </summary> /// <param name="entitys">插入實體集合</param> /// <param name="dataBaseName">數據名稱</param> /// <param name="tableName">表名</param> /// <param name="excludeProperties">過濾屬性名稱列表</param> /// <returns>SQL參數集合</returns> public static bool ExecuteInsertModelBatch<T>(List<T> entitys, string dataBaseName, string tableName = "", params string[] excludeProperties) { bool isSucceed = false; List<MySqlParameter> sqlParameters = new List<MySqlParameter>(); string sql = string.Empty; sqlParameters = GetInsertSqlBatch(entitys, out sql, tableName, excludeProperties); if (sql.Length > 0 && sqlParameters != null && sqlParameters.Count > 0) { try { isSucceed = CBDMySqlHelper.ExecuteNonQuery(dataBaseName, sql, sqlParameters.ToArray()) == entitys.Count; } catch (Exception ex) { throw ex; } finally { if (sqlParameters != null && sqlParameters.Count > 0) { sqlParameters.Clear(); sqlParameters = null; } if (entitys != null && entitys.Count > 0) { entitys.Clear(); entitys = null; } } } return isSucceed; } /// <summary> /// 執行批量插入實體方法 /// </summary> /// <param name="entitys">插入實體集合</param> /// <param name="batchNum">分批處理數量[<=0時默認值爲100]</param> /// <param name="batchNum">每一個批量插入的數量</param> /// <param name="dataBaseName">數據名稱</param> /// <param name="tableName">表名</param> /// <param name="excludeProperties">過濾屬性名稱列表</param> /// <returns>SQL參數集合</returns> public static bool ExecuteInsertModelBatch<T>(List<T> entitys, int batchNum, string dataBaseName, string tableName = "", params string[] excludeProperties) { bool isSucceed = false; var insertCount = 0; List<MySqlParameter> sqlParameters = new List<MySqlParameter>(); if (entitys != null && entitys.Count > 0) { //若是分批處理數量爲0時,則使用默認值100 if (batchNum <= 0) { batchNum = 100; } var type = entitys.First().GetType(); tableName = GetTableName(type, tableName); //INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) // VALUES ('0', 'userid_0', 'content_0', 0), // ('1', 'userid_1', 'content_1', 1); if (!string.IsNullOrEmpty(tableName)) { StringBuilder InsertSql = new StringBuilder(string.Format("Insert into {0}(", tableName.ToLower())); StringBuilder ValuesSql = new StringBuilder(" Values("); var propertieList = GetProperties(type); var entityItemIndex = 1; try { //循環要插入的實體集合 foreach (var entityItem in entitys) { //循環每一個實體的屬性集合 var propertieIndex = 0; foreach (var propertieItem in propertieList.Values) { //是否添加屬性 if (ValidateIsAddPropertie(type, propertieItem, OperationType.Insert, paramsArrayToDictionary(excludeProperties))) { if (entityItemIndex == 1) { InsertSql.AppendFormat("{0},", propertieItem.Name); } var parameterName = string.Format("@{0}{1}", propertieItem.Name, entityItemIndex); if (entityItemIndex > 1 && propertieIndex == 0) { ValuesSql.Append("("); } ValuesSql.AppendFormat("{0},", parameterName); var value = propertieItem.GetValue(entityItem); sqlParameters.Add(new MySqlParameter(parameterName, value ?? string.Empty)); } if (propertieIndex == propertieList.Count - 1) { if (entityItemIndex == 1) { InsertSql.Remove(InsertSql.Length - 1, 1); InsertSql.Append(")"); } ValuesSql.Remove(ValuesSql.Length - 1, 1); ValuesSql.Append("),"); } propertieIndex++; } if ((entityItemIndex % batchNum) == 0 || entityItemIndex == entitys.Count) { var sql = string.Format("{0}{1}", InsertSql, ValuesSql).Trim(','); insertCount += CBDMySqlHelper.ExecuteNonQuery(dataBaseName, sql, sqlParameters.ToArray()); ValuesSql = new StringBuilder(" Values"); sqlParameters.Clear(); } entityItemIndex++; } if (insertCount == entitys.Count) { isSucceed = true; } } catch (Exception ex) { InsertSql.Clear(); ValuesSql.Clear(); if (sqlParameters != null && sqlParameters.Count > 0) { sqlParameters.Clear(); sqlParameters = null; } throw ex; } finally { if (entitys != null && entitys.Count > 0) { entitys.Clear(); entitys = null; } } } } return isSucceed; }