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