createinbatches是批量插入首选方法,因其将多条记录合并为单条多值insert语句,显著减少网络往返、sql解析和事务开销;它原生支持gorm v2+,自动处理时间字段和钩子,但需手动控制事务、合理设置batchsize(如50–500)并检查错误。

为什么 CreateInBatches 是批量插入的首选方法
直接用循环调用 Create 会触发 N 次 SQL INSERT,性能极差;而 CreateInBatches 能把多个记录合并成一条或多条 INSERT INTO ... VALUES (...), (...), (...) 语句,显著减少网络往返和事务开销。它原生支持 GORM v2+,无需手动拼 SQL 或引入第三方包。
注意:该方法内部仍是一次性提交一个批次(默认 100 条),不是真正“流式”插入,但已覆盖绝大多数场景。
- 批次大小可通过第二个参数控制,例如
db.CreateInBatches(orders, 50) - 若传入空切片,GORM 不会报错,但也不会执行任何 SQL
- 主键自增时,
CreateInBatches仍能正确回填ID字段(依赖数据库 RETURNING 或 LAST_INSERT_ID)
遇到 ERROR: duplicate key value violates unique constraint 怎么办
批量插入时唯一约束冲突不会中断整个批次——GORM 默认继续执行,但失败记录的 ID 和其他字段不会被更新,且错误仅体现在返回的 error 中,容易被忽略。
必须显式检查错误并定位失败项:
err := db.CreateInBatches(articles, 100).Error
if err != nil {
// 注意:err 是 *mysql.MySQLError 或 *pq.Error,可类型断言提取 code
if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1062 {
// 处理重复键
}
}
- PostgreSQL 用户可用
ON CONFLICT DO NOTHING替代方案(需配合Clause(clause.OnConflict{DoNothing: true})) - MySQL 用户无法在
INSERT ... VALUES中优雅跳过重复项,建议先SELECT过滤已存在 ID,或改用INSERT IGNORE(需自行构造原生 SQL) - 不要依赖
RowsAffected判断成功数——它只反映最终影响行数,不区分跳过/失败/新增
CreateInBatches 和原生 Exec 批量插入的区别在哪
用 db.Exec("INSERT INTO ...", args...) 确实更快,但它绕过了 GORM 的模型映射、钩子(BeforeCreate)、软删除字段处理、甚至事务上下文。除非你明确需要极致性能且能接受失去 ORM 层保障,否则不推荐。
-
CreateInBatches会触发BeforeCreate/AfterCreate钩子,原生Exec完全不会 - 时间字段如
CreatedAt在CreateInBatches中自动赋值,原生 SQL 需手动写NOW()或传参 - 关联字段(
gorm:"foreignKey:UserID")在CreateInBatches中照常生效;原生 SQL 需自己确保外键值合法 - SQLite 用户注意:
CreateInBatches在 v1.23+ 才支持多值 INSERT,旧版会退化为单条循环
事务内使用 CreateInBatches 的注意事项
它本身不开启新事务,完全依赖当前 DB 实例的事务状态。如果在 db.Transaction(func(tx *gorm.DB) error { ... }) 内调用,一切正常;但如果误用未开启事务的 db 实例,失败后无法回滚整个批次。
- 务必确认
db是事务对象(tx := db.Begin()),而非全局db - 批次过大(如 10000+)可能触发 MySQL 的
max_allowed_packet限制,报错ERROR 2020 (HY000): Got packet bigger than 'max_allowed_packet' bytes,此时应降低批次大小 - PostgreSQL 对单条 INSERT 的元组数量无硬限制,但过长 SQL 可能影响解析性能,建议单批次不超过 1000
真正麻烦的是跨表批量操作——比如同时插用户和订单,不能指望一个 CreateInBatches 覆盖多个模型。得拆成多个调用,并确保它们在同一个事务里。这点很容易漏掉。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











