GORM 提供了 Session
方法,这是一个 New Session Method
,它允许创建带配置的新建会话模式:
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...)
预编译 PreparedStmt
在执行任何 SQL 时都会创建一个 prepared statement 并将其缓存,以提高后续的效率,例如:
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)
初始化 Create a new initialized DB, which is not Method Chain/Goroutine Safe anymore, refer Method Chaining
tx := db.Session(&gorm.Session{Initialized: true })
跳过钩子 如果您想跳过 钩子
方法,您可以使用 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)
禁用嵌套事务 在一个 DB 事务中使用 Transaction
方法,GORM 会使用 SavePoint(savedPointName)
,RollbackTo(savedPointName)
为你提供嵌套事务支持。 你可以通过 DisableNestedTransaction
选项关闭它,例如:
db.Session(&gorm.Session{ DisableNestedTransaction: true , }).CreateInBatches(&users, 100 )
AllowGlobalUpdate GORM 默认不允许进行全局 update/delete,该操作会返回 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
选项,您可以传入 Context
来追踪 SQL 操作,例如:
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
选项自定义内建 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)})
查看 Logger 获取更多信息.
NowFunc NowFunc
允许改变 GORM 获取当前时间的实现,例如:
db.Session(&Session{ NowFunc: func () time.Time { return time.Now().Local() }, })
调试 Debug
只是将会话的 Logger
修改为调试模式的简写形式,其实现如下:
func (db *DB) Debug() (tx *DB) { return db.Session(&Session{ Logger: db.Logger.LogMode(logger.Info), }) }
查询字段 声明查询字段
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)