GORM 提供了 Session
方法,这是一个 New Session Method
,它允许创建带配置的新建会话模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 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:
1 2 3 db.Dialector.Explain(stmt.SQL.String(), stmt.Vars...)
预编译 PreparedStmt
在执行任何 SQL 时都会创建一个 prepared statement 并将其缓存,以提高后续的效率,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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,例如:
1 2 3 4 5 6 7 8 9 10 11 12 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
1 tx := db.Session(&gorm.Session{Initialized: true })
跳过钩子 如果您想跳过 钩子
方法,您可以使用 SkipHooks
会话模式,例如:
1 2 3 4 5 6 7 8 9 10 11 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
选项关闭它,例如:
1 2 3 db.Session(&gorm.Session{ DisableNestedTransaction: true , }).CreateInBatches(&users, 100 )
AllowGlobalUpdate GORM 默认不允许进行全局 update/delete,该操作会返回 ErrMissingWhereClause
错误。 您可以通过将一个选项设置为 true 来启用它,例如:
1 2 3 4 db.Session(&gorm.Session{ AllowGlobalUpdate: true , }).Model(&User{}).Update("name" , "jinzhu" )
FullSaveAssociations 在创建、更新记录时,GORM 会通过 Upsert 自动保存关联及其引用记录。 如果您想要更新关联的数据,您应该使用 FullSaveAssociations
模式,例如:
1 2 3 4 5 6 db.Session(&gorm.Session{FullSaveAssociations: true }).Updates(&user)
Context 通过 Context
选项,您可以传入 Context
来追踪 SQL 操作,例如:
1 2 3 4 5 timeoutCtx, _ := context.WithTimeout(context.Background(), time.Second) tx := db.Session(&Session{Context: timeoutCtx}) tx.First(&user) tx.Model(&user).Update("role" , "admin" )
GORM 也提供了简写形式的方法 WithContext
,其实现如下:
1 2 3 func (db *DB) WithContext (ctx context.Context) *DB { return db.Session(&Session{Context: ctx}) }
自定义 Logger Gorm 允许使用 Logger
选项自定义内建 Logger,例如:
1 2 3 4 5 6 7 8 9 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 获取当前时间的实现,例如:
1 2 3 4 5 db.Session(&Session{ NowFunc: func () time .Time { return time.Now().Local() }, })
调试 Debug
只是将会话的 Logger
修改为调试模式的简写形式,其实现如下:
1 2 3 4 5 func (db *DB) Debug () (tx *DB) { return db.Session(&Session{ Logger: db.Logger.LogMode(logger.Info), }) }
查询字段 声明查询字段
1 2 3 db.Session(&gorm.Session{QueryFields: true }).Find(&user)
CreateBatchSize 默认批量大小
1 2 3 4 5 users = [5000 ]User{{Name: "jinzhu" , Pets: []Pet{pet1, pet2, pet3}}...} db.Session(&gorm.Session{CreateBatchSize: 1000 }).Create(&users)