sequence
This paper focuses on CreateInBatches of GORM
CreateInBatches
Gorm. IO/[email protected] / finisher_api. Go
// CreateInBatches insert the value in batches into database func (db *DB) CreateInBatches(value interface{}, batchSize int) (tx *DB) { reflectValue := reflect.Indirect(reflect.ValueOf(value)) switch reflectValue.Kind() { case reflect.Slice, reflect.Array: var rowsAffected int64 tx = db.getInstance() tx.AddError(tx.Transaction(func(tx *DB) error { for i := 0; i < reflectValue.Len(); i += batchSize { ends := i + batchSize if ends > reflectValue.Len() { ends = reflectValue.Len() } subtx := tx.getInstance() subtx.Statement.Dest = reflectValue.Slice(i, ends).Interface() subtx.callbacks.Create().Execute(subtx) if subtx.Error ! = nil { return subtx.Error } rowsAffected += subtx.RowsAffected } return nil })) tx.RowsAffected = rowsAffected default: tx = db.getInstance() tx.Statement.Dest = value tx.callbacks.Create().Execute(tx) } return }Copy the code
CreateInBatches are assigned to create a batch according to batchSize, but they are created in the same transaction, with rowsAffected nodes being the sum of each batch’s rowsAffected nodes
AddError
Gorm. IO/[email protected] / gorm. Go
// AddError add error to db func (db *DB) AddError(err error) error { if db.Error == nil { db.Error = err } else if err ! = nil { db.Error = fmt.Errorf("%v; %w", db.Error, err) } return db.Error }Copy the code
The tx.adderror method updates to err directly if db.Error is nil; If err is not nil, check whether err is nil. If err is not nil, update err
CommitOrRollbackTransaction
Gorm. IO/[email protected] / callbacks/transaction. Go
func CommitOrRollbackTransaction(db *gorm.DB) { if ! db.Config.SkipDefaultTransaction { if _, ok := db.InstanceGet("gorm:started_transaction"); ok { if db.Error == nil { db.Commit() } else { db.Rollback() } db.Statement.ConnPool = db.ConnPool } } }Copy the code
CommitOrRollbackTransaction method can determine the db. The Error, if not for nil execute the Rollback ()
The instance
func createInBatchesDemo(db *gorm.DB) {
entities := []DemoEntity{
{
Name: "coco",
},
{
Name: "bear",
},
}
result := db.Debug().CreateInBatches(&entities, 1)
b, _ := json.Marshal(entities)
log.Println("data:", string(b))
log.Println("result.RowsAffected:", result.RowsAffected, "result.Error:", result.Error)
}
Copy the code
The output
2021/01/16 22:28:55 /demo.go:71 [rows:1] INSERT INTO 'demo_entities' (` created_at `, ` updated_at `, ` deleted_at `, ` name `) VALUES (" 2021-01-16 22:28:55. 774 ", "the 2021-01-16 22:28:55. 774", NULL, "coco") 2021/01/16 22:28:55 /demo.go:71 [rows:1] INSERT INTO 'demo_entities' (` created_at `, ` updated_at `, ` deleted_at `, ` name `) VALUES (" 2021-01-16 22:28:55. 774 ", "the 2021-01-16 22:28:55. 774", NULL, "bear") 2021/01/16 22:28:55 data: [{" ID ": 7," CreatedAt ":" the 2021-01-16 T22:28:55. 7743 + 08:00 ", "UpdatedAt" : "the 2021-01-16 T22:28:55. 7743 + 08:00", "DeletedAt:" null, "Nam E ", "coco"}, {" ID ": 8," CreatedAt ":" the 2021-01-16 T22:28:55. 774794 + 08:00 ", "UpdatedAt" : "the 2021-01-16 T22:28:55. 774794 + 08:00", "Delete dAt":null,"Name":"bear"}] 2021/01/16 22:28:55 result.RowsAffected: 2 result.Error: <nil>Copy the code
summary
Gorm’s CreateInBatches label allows users to define a batch’s Own batchSize. The CREATED images are assigned according to the batchSize, but they are in the same transaction, and their rowsAffected nodes are the sum of each batch’s rowsAffected nodes.
doc
- gorm