Context

原文:https://gorm.io/docs/context.html

GORM provides Context support, you can use it with method WithContext

​ GORM提供了Context支持,你可以使用WithContext方法来使用它。

单次会话模式 Single Session Mode

Single session mode usually used when you want to perform a single operation

​ 单次会话模式通常用于执行单个操作,例如:

1
db.WithContext(ctx).Find(&users)

连续会话模式 Continuous session mode

Continuous session mode is usually used when you want to perform a group of operations, for example:

​ 连续会话模式通常用于执行一组操作,例如:

1
2
3
tx := db.WithContext(ctx)
tx.First(&user, 1)
tx.Model(&user).Update("role", "admin")

上下文超时 Context timeout

You can pass in a context with a timeout to db.WithContext to set timeout for long running queries, for example:

​ 您可以将带有超时的上下文传递给db.WithContext以设置长时间运行查询的超时时间,例如:

1
2
3
4
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

db.WithContext(ctx).Find(&users)

钩子/回调中的上下文 Context in Hooks/Callbacks

You can access the Context object from the current Statement, for example:

​ 您可以从当前Statement访问Context对象,例如:

1
2
3
4
5
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
  ctx := tx.Statement.Context
  // ...
  return
}

Chi中间件示例 Chi Middleware Example

Continuous session mode which might be helpful when handling API requests, for example, you can set up *gorm.DB with Timeout Context in middlewares, and then use the *gorm.DB when processing all requests

​ 在处理API请求时,连续会话模式可能很有用,例如,您可以在中间件中设置带有超时上下文的*gorm.DB,然后在处理所有请求时使用该*gorm.DB

Following is a Chi middleware example:

​ 以下是Chi中间件示例:

 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
func SetDBMiddleware(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    timeoutContext, _ := context.WithTimeout(context.Background(), time.Second)
    ctx := context.WithValue(r.Context(), "DB", db.WithContext(timeoutContext))
    next.ServeHTTP(w, r.WithContext(ctx))
  })
}

r := chi.NewRouter()
r.Use(SetDBMiddleware)

r.Get("/", func(w http.ResponseWriter, r *http.Request) {
  db, ok := ctx.Value("DB").(*gorm.DB)

  var users []User
  db.Find(&users)

  // lots of db operations
})

r.Get("/user", func(w http.ResponseWriter, r *http.Request) {
  db, ok := ctx.Value("DB").(*gorm.DB)

  var user User
  db.First(&user)

  // lots of db operations
})

NOTE Setting Context with WithContext is goroutine-safe, refer Session for details

注意 使用WithContext设置Context是线程安全的,请参阅Session以获取详细信息

日志记录器 Logger

Logger accepts Context too, you can use it for log tracking, refer Logger for details

​ 日志记录器也接受Context,您可以使用它进行日志跟踪,请参阅Logger以获取详细信息

最后修改 October 10, 2024: 更新 (a4b8f85)