教程

会话

qianmoQqianmoQ· 更新于 2026-09-23· 阅读 12 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

GORM 提供了 Session 方法,它是一个新会话方法,允许通过配置创建新的会话模式:


type Session struct {
  DryRun                   bool
  PrepareStmt              bool
  NewDB                    bool
  Initialized              bool
  SkipHooks                bool
  SkipDefaultTransaction   bool
  DisableNestedTransaction bool
  AllowGlobalUpdate        bool
  FullSaveAssociations     bool
  QueryFields              bool
  Context                  context.Context
  Logger                   logger.Interface
  NowFunc                  func() time.Time
  CreateBatchSize          int
}

DryRun

生成 SQL 但不执行。可用于准备或测试生成的 SQL,例如:


stmt := db.Session(&Session{DryRun: true}).First(&user, 1).Statement
stmt.SQL.String() 
stmt.Vars         


db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{DryRun: true})


stmt := db.Find(&user, 1).Statement
stmt.SQL.String() 
stmt.SQL.String() 
stmt.Vars         

要生成最终的 SQL,可以使用以下代码:


db.Dialector.Explain(stmt.SQL.String(), stmt.Vars...)

PrepareStmt

PreparedStmt 在执行任何 SQL 时创建预处理语句并将其缓存,以加速后续调用,例如:


db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
  PrepareStmt: true,
})


tx := db.Session(&Session{PrepareStmt: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)


stmtManger, ok := tx.ConnPool.(*PreparedStmtDB)


stmtManger.Close()


stmtManger.PreparedSQL 


stmtManger.Stmts 

for sql, stmt := range stmtManger.Stmts {
  sql  
  stmt 
  stmt.Close() 
}

NewDB

使用 NewDB 选项创建一个没有条件的新 DB,例如:

tx := db.Where("name = ?", "jinzhu").Session(&gorm.Session{NewDB: true})

tx.First(&user)


tx.First(&user, "id = ?", 10)



tx2 := db.Where("name = ?", "jinzhu").Session(&gorm.Session{})
tx2.First(&user)

Initialized

创建一个已初始化的新 DB,它不再是方法链/协程安全的,请参阅方法链

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

Skip Hooks(跳过钩子)

如果想跳过 Hooks 方法,可以使用 SkipHooks 会话模式,例如:

DB.Session(&gorm.Session{SkipHooks: true}).Create(&user)

DB.Session(&gorm.Session{SkipHooks: true}).Create(&users)

DB.Session(&gorm.Session{SkipHooks: true}).CreateInBatches(users, 100)

DB.Session(&gorm.Session{SkipHooks: true}).Find(&user)

DB.Session(&gorm.Session{SkipHooks: true}).Delete(&user)

DB.Session(&gorm.Session{SkipHooks: true}).Model(User{}).Where("age > ?", 18).Updates(&user)

DisableNestedTransaction

在 DB 事务内使用 Transaction 方法时,GORM 会使用 SavePoint(savedPointName)、RollbackTo(savedPointName) 来提供嵌套事务支持。可以通过 DisableNestedTransaction 选项禁用此功能,例如:

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

AllowGlobalUpdate

GORM 默认不允许全局更新/删除,会返回 ErrMissingWhereClause 错误。可以将此选项设置为 true 来启用它,例如:

db.Session(&gorm.Session{
  AllowGlobalUpdate: true,
}).Model(&User{}).Update("name", "jinzhu")

FullSaveAssociations

GORM 在创建/更新记录时会自动保存关联及其引用,使用 Upsert。如果想更新关联的数据,应使用 FullSaveAssociations 模式,例如:

db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)




Context

通过 Context 选项,可以为后续的 SQL 操作设置 Context,例如:

timeoutCtx, _ := context.WithTimeout(context.Background(), time.Second)
tx := db.Session(&Session{Context: timeoutCtx})

tx.First(&user) 
tx.Model(&user).Update("role", "admin") 

GORM 还提供了快捷方法 WithContext,其定义如下:

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

Logger

GORM 允许通过 Logger 选项自定义内置日志记录器,例如:

newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags),
              logger.Config{
                SlowThreshold: time.Second,
                LogLevel:      logger.Silent,
                Colorful:      false,
              })
db.Session(&Session{Logger: newLogger})

db.Session(&Session{Logger: logger.Default.LogMode(logger.Silent)})

更多详情请参阅 日志。

NowFunc

NowFunc 允许更改 GORM 获取当前时间的函数,例如:

db.Session(&Session{
  NowFunc: func() time.Time {
    return time.Now().Local()
  },
})

Debug

Debug 是一个快捷方法,用于将会话的 Logger 切换到调试模式,其定义如下:

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

QueryFields

按字段进行选择

db.Session(&gorm.Session{QueryFields: true}).Find(&user)

CreateBatchSize

默认批量大小

users = [5000]User{{Name: "jinzhu", Pets: []Pet{pet1, pet2, pet3}}...}

db.Session(&gorm.Session{CreateBatchSize: 1000}).Create(&users)

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…