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)