var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" +
"Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10";
static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, connstr)
.UseAutoSyncStructure(true) //自動同步實體結構到數據庫
.Build(); //請務必定義成 Singleton 單例模式
[Table(Name = "tb_topic")]
class Topic {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
public int Clicks { get; set; }
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
批量插入
var items = new List<Topic>();
for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
fsql.Insert(items).ExecuteAffrows();
執行SQL如下:
INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`)
VALUES(?Clicks0, ?Title0, ?CreateTime0),
(?Clicks1, ?Title1, ?CreateTime1),
(?Clicks2, ?Title2, ?CreateTime2),
(?Clicks3, ?Title3, ?CreateTime3),
(?Clicks4, ?Title4, ?CreateTime4),
(?Clicks5, ?Title5, ?CreateTime5),
(?Clicks6, ?Title6, ?CreateTime6),
(?Clicks7, ?Title7, ?CreateTime7),
(?Clicks8, ?Title8, ?CreateTime8),
(?Clicks9, ?Title9, ?CreateTime9)
內部設計
當插入大批量數據時,內部采用分割分批執行的邏輯進行。分割規則如下:
數量 | 參數量 | |
---|---|---|
MySql | 5000 | 3000 |
PostgreSQL | 5000 | 3000 |
SqlServer | 1000 | 2100 |
Oracle | 500 | 999 |
Sqlite | 5000 | 999 |
數據:為每批分割的大小,如批量插入 10000 條數據,在 mysql 執行時會分割為兩批。
參數量:為每批分割的參數量大小,如批量插入 10000 條數據,每行需要使用 5 個參數化,在 mysql 執行時會分割為每批 3000 / 5。
分割執行后,當外部未提供事務時,內部自開事務,實現插入完整性。
FreeSql 適配了每一種數據類型參數化,和不參數化的使用。批量插入建議關閉參數化功能,使用 .NonoParameter() 進行執行(有關 NoneParameter 在后續文章介紹)。
性能參考
API
方法 | 返回值 | 參數 | 描述 |
---|---|---|---|
AppendData | <this> | T1 | IEnumerable
|
追加准備插入的實體 |
ToSql | string | 返回即將執行的SQL語句 | |
ExecuteAffrows | long | 執行SQL語句,返回影響的行數 | |
ExecuteIdentity | long | 執行SQL語句,返回自增值 | |
ExecuteInserted | List<T1> | 執行SQL語句,返回插入后的記錄 | |
ExecuteSqlBulkCopy | void | SqlServer 特有的功能,執行 SqlBulkCopy 批量插入的封裝 | |
ExecutePgCopy | void | PostgreSQL 特有的功能,執行 Copy 批量導入數據 |
系列文章導航
-
(六)批量插入數據