GORM provides Session method, which is a New Session Method, it allows to create a new session mode with configuration:

  1. // Session Configuration
  2. type Session struct {
  3. DryRun bool
  4. PrepareStmt bool
  5. NewDB bool
  6. Initialized bool
  7. SkipHooks bool
  8. SkipDefaultTransaction bool
  9. DisableNestedTransaction bool
  10. AllowGlobalUpdate bool
  11. FullSaveAssociations bool
  12. QueryFields bool
  13. Context context.Context
  14. Logger logger.Interface
  15. NowFunc func() time.Time
  16. CreateBatchSize int
  17. }

DryRun

Generates SQL without executing. It can be used to prepare or test generated SQL, for example:

  1. // session mode
  2. stmt := db.Session(&Session{DryRun: true}).First(&user, 1).Statement
  3. stmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = $1 ORDER BY `id`
  4. stmt.Vars //=> []interface{}{1}
  5. // globally mode with DryRun
  6. db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{DryRun: true})
  7. // different databases generate different SQL
  8. stmt := db.Find(&user, 1).Statement
  9. stmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = $1 // PostgreSQL
  10. stmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = ? // MySQL
  11. stmt.Vars //=> []interface{}{1}

To generate the final SQL, you could use following code:

  1. // NOTE: the SQL is not always safe to execute, GORM only uses it for logs, it might cause SQL injection
  2. db.Dialector.Explain(stmt.SQL.String(), stmt.Vars...)
  3. // SELECT * FROM `users` WHERE `id` = 1

PrepareStmt

PreparedStmt creates prepared statements when executing any SQL and caches them to speed up future calls, for example:

  1. // globally mode, all DB operations will create prepared statements and cache them
  2. db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
  3. PrepareStmt: true,
  4. })
  5. // session mode
  6. tx := db.Session(&Session{PrepareStmt: true})
  7. tx.First(&user, 1)
  8. tx.Find(&users)
  9. tx.Model(&user).Update("Age", 18)
  10. // returns prepared statements manager
  11. stmtManger, ok := tx.ConnPool.(*PreparedStmtDB)
  12. // close prepared statements for *current session*
  13. stmtManger.Close()
  14. // prepared SQL for *current session*
  15. stmtManger.PreparedSQL // => []string{}
  16. // prepared statements for current database connection pool (all sessions)
  17. stmtManger.Stmts // map[string]*sql.Stmt
  18. for sql, stmt := range stmtManger.Stmts {
  19. sql // prepared SQL
  20. stmt // prepared statement
  21. stmt.Close() // close the prepared statement
  22. }

NewDB

Create a new DB without conditions with option NewDB, for example:

  1. tx := db.Where("name = ?", "jinzhu").Session(&gorm.Session{NewDB: true})
  2. tx.First(&user)
  3. // SELECT * FROM users ORDER BY id LIMIT 1
  4. tx.First(&user, "id = ?", 10)
  5. // SELECT * FROM users WHERE id = 10 ORDER BY id
  6. // Without option `NewDB`
  7. tx2 := db.Where("name = ?", "jinzhu").Session(&gorm.Session{})
  8. tx2.First(&user)
  9. // SELECT * FROM users WHERE name = "jinzhu" ORDER BY id

Initialized

Create a new initialized DB, which is not Method Chain/Goroutine Safe anymore, refer Method Chaining

  1. tx := db.Session(&gorm.Session{Initialized: true})

Skip Hooks

If you want to skip Hooks methods, you can use the SkipHooks session mode, for example:

  1. DB.Session(&gorm.Session{SkipHooks: true}).Create(&user)
  2. DB.Session(&gorm.Session{SkipHooks: true}).Create(&users)
  3. DB.Session(&gorm.Session{SkipHooks: true}).CreateInBatches(users, 100)
  4. DB.Session(&gorm.Session{SkipHooks: true}).Find(&user)
  5. DB.Session(&gorm.Session{SkipHooks: true}).Delete(&user)
  6. DB.Session(&gorm.Session{SkipHooks: true}).Model(User{}).Where("age > ?", 18).Updates(&user)

DisableNestedTransaction

When using Transaction method inside a DB transaction, GORM will use SavePoint(savedPointName), RollbackTo(savedPointName) to give you the nested transaction support. You can disable it by using the DisableNestedTransaction option, for example:

  1. db.Session(&gorm.Session{
  2. DisableNestedTransaction: true,
  3. }).CreateInBatches(&users, 100)

AllowGlobalUpdate

GORM doesn’t allow global update/delete by default, will return ErrMissingWhereClause error. You can set this option to true to enable it, for example:

  1. db.Session(&gorm.Session{
  2. AllowGlobalUpdate: true,
  3. }).Model(&User{}).Update("name", "jinzhu")
  4. // UPDATE users SET `name` = "jinzhu"

FullSaveAssociations

GORM will auto-save associations and its reference using Upsert when creating/updating a record. If you want to update associations’ data, you should use the FullSaveAssociations mode, for example:

  1. db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)
  2. // ...
  3. // INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1"), ("Shipping Address - Address 1") ON DUPLICATE KEY SET address1=VALUES(address1);
  4. // INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);
  5. // INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu@example.com"), (111, "jinzhu-2@example.com") ON DUPLICATE KEY SET email=VALUES(email);
  6. // ...

Context

With the Context option, you can set the Context for following SQL operations, for example:

  1. timeoutCtx, _ := context.WithTimeout(context.Background(), time.Second)
  2. tx := db.Session(&Session{Context: timeoutCtx})
  3. tx.First(&user) // query with context timeoutCtx
  4. tx.Model(&user).Update("role", "admin") // update with context timeoutCtx

GORM also provides shortcut method WithContext, here is the definition:

  1. func (db *DB) WithContext(ctx context.Context) *DB {
  2. return db.Session(&Session{Context: ctx})
  3. }

Logger

Gorm allows customizing built-in logger with the Logger option, for example:

  1. newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags),
  2. logger.Config{
  3. SlowThreshold: time.Second,
  4. LogLevel: logger.Silent,
  5. Colorful: false,
  6. })
  7. db.Session(&Session{Logger: newLogger})
  8. db.Session(&Session{Logger: logger.Default.LogMode(logger.Silent)})

Checkout Logger for more details.

NowFunc

NowFunc allows changing the function to get current time of GORM, for example:

  1. db.Session(&Session{
  2. NowFunc: func() time.Time {
  3. return time.Now().Local()
  4. },
  5. })

Debug

Debug is a shortcut method to change session’s Logger to debug mode, here is the definition:

  1. func (db *DB) Debug() (tx *DB) {
  2. return db.Session(&Session{
  3. Logger: db.Logger.LogMode(logger.Info),
  4. })
  5. }

QueryFields

Select by fields

  1. db.Session(&gorm.Session{QueryFields: true}).Find(&user)
  2. // SELECT `users`.`name`, `users`.`age`, ... FROM `users` // with this option
  3. // SELECT * FROM `users` // without this option

CreateBatchSize

Default batch size

  1. users = [5000]User{{Name: "jinzhu", Pets: []Pet{pet1, pet2, pet3}}...}
  2. db.Session(&gorm.Session{CreateBatchSize: 1000}).Create(&users)
  3. // INSERT INTO users xxx (5 batches)
  4. // INSERT INTO pets xxx (15 batches)