教程
上下文
登录后可跨设备保存划线和私人笔记登录
GORM 的上下文支持是一项强大的功能,它增强了 Go 应用程序中数据库操作的灵活性和控制力。它允许在不同的操作模式、超时设置以及钩子/回调和中间件集成中进行上下文管理。让我们来深入了解这些不同的方面:
单会话模式
单会话模式适用于执行单个操作。它确保特定操作在上下文的范围内执行,从而实现更好的控制和监控。
泛型 API
使用泛型 API 时,上下文作为操作方法的第一个参数直接传递:
users, err := gorm.G[User](db).Find(ctx)传统 API
使用传统 API 时,通过 WithContext 方法传递上下文:
db.WithContext(ctx).Find(&users)连续会话模式
连续会话模式适合执行一系列相关操作。它在这些操作之间保持上下文,这在事务等场景中尤其有用。
tx := db.WithContext(ctx)
tx.First(&user, 1)
tx.Model(&user).Update("role", "admin")上下文超时
在上下文上设置超时可以控制长时间运行的查询的持续时间。这对于维持性能和避免数据库交互中的资源锁定至关重要。
泛型 API
使用泛型 API 时,将超时上下文直接传递给操作:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
users, err := gorm.G[User](db).Find(ctx)传统 API
使用传统 API 时,将超时上下文传递给 WithContext:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
db.WithContext(ctx).Find(&users)钩子/回调中的上下文
上下文也可以在 GORM 的钩子/回调中访问。这使得上下文信息可以在这些生命周期事件中被使用。上下文通过 Statement.Context 字段访问:
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
ctx := tx.Statement.Context
return
}与 Chi 中间件集成
GORM 的上下文支持扩展到了 Web 服务器中间件,例如 Chi 路由器中的中间件。这允许为 Web 请求范围内的所有数据库操作设置带有超时的上下文。
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 := r.Context().Value("DB").(*gorm.DB)
})
r.Get("/user", func(w http.ResponseWriter, r *http.Request) {
db, ok := r.Context().Value("DB").(*gorm.DB)
})注意:通过 WithContext 设置 Context 是 goroutine 安全的。这确保了数据库操作在多个 goroutine 之间的安全管理。更多详情请参阅 GORM 的 Session 文档。
日志记录器集成
GORM 的日志记录器也接受 Context,可用于日志跟踪和与现有日志基础设施的集成。
更多详情请参阅 Logger 文档。
评论
登录后参与评论
正在加载评论…
KnowForge