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}
6. // globally mode with DryRun
7. db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{DryRun: true})
9. // different databases generate different SQL
10. stmt := db.Find(&user, 1).Statement
11. stmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = $1 // PostgreSQL
12. stmt.SQL.String() //=> SELECT * FROM `users` WHERE `id` = ? // MySQL
13. 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. })
6. // session mode
7. tx := db.Session(&Session{PrepareStmt: true})
8. tx.First(&user, 1)
9. tx.Find(&users)
10. tx.Model(&user).Update("Age", 18)
12. // returns prepared statements manager
13. stmtManger, ok := tx.ConnPool.(*PreparedStmtDB)
15. // close prepared statements for *current session*
16. stmtManger.Close()
18. // prepared SQL for *current session*
19. stmtManger.PreparedSQL // => []string{}
21. // prepared statements for current database connection pool (all sessions)
22. stmtManger.Stmts // map[string]*sql.Stmt
24. for sql, stmt := range stmtManger.Stmts {
25. sql // prepared SQL
26. stmt // prepared statement
27. stmt.Close() // close the prepared statement
28. }
NewDB
Create a new DB without conditions with option NewDB, for example:
1. tx := db.Where("name = ?", "jinzhu").Session(&gorm.Session{NewDB: true})
3. tx.First(&user)
4. // SELECT * FROM users ORDER BY id LIMIT 1
6. tx.First(&user, "id = ?", 10)
7. // SELECT * FROM users WHERE id = 10 ORDER BY id
9. // Without option `NewDB`
10. tx2 := db.Where("name = ?", "jinzhu").Session(&gorm.Session{})
11. tx2.First(&user)
12. // SELECT * FROM users WHERE name = "jinzhu" ORDER BY id
Initialized
Create a new initialized DB, which is not Method Chain/Gortoutine 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)
3. DB.Session(&gorm.Session{SkipHooks: true}).Create(&users)
5. DB.Session(&gorm.Session{SkipHooks: true}).CreateInBatches(users, 100)
7. DB.Session(&gorm.Session{SkipHooks: true}).Find(&user)
9. DB.Session(&gorm.Session{SkipHooks: true}).Delete(&user)
11. 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})
4. tx.First(&user) // query with context timeoutCtx
5. 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})
9. 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}}...}
3. db.Session(&gorm.Session{CreateBatchSize: 1000}).Create(&users)
4. // INSERT INTO users xxx (5 batches)
5. // INSERT INTO pets xxx (15 batches)
