扫码一下
查看教程更方便
gorm 通过 withcontext
方法提供了 context 支持
单会话模式通常被用于执行单次操作
db.withcontext(ctx).find(&users)
持续会话模式通常被用于执行一系列操作,例如:
tx := db.withcontext(ctx)
tx.first(&user, 1)
tx.model(&user).update("role", "admin")
对于长 sql 查询,你可以传入一个带超时的 context 给 db.withcontext
来设置超时时间,例如:
ctx, cancel := context.withtimeout(context.background(), 2*time.second)
defer cancel()
db.withcontext(ctx).find(&users)
我们可以从当前 statement
中访问 context 对象,例如︰
func (u *user) beforecreate(tx *gorm.db) (err error) {
ctx := tx.statement.context
// ...
return
}
在处理 api 请求时持续会话模式会比较有用。例如,您可以在中间件中为 *gorm.db 设置超时 context,然后使用 *gorm.db 处理所有请求
下面是一个 chi 中间件的示例:
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)
// 你的其他 db 操作...
})
r.get("/user", func(w http.responsewriter, r *http.request) {
db, ok := ctx.value("db").(*gorm.db)
var user user
db.first(&user)
// 你的其他 db 操作...
})
注意
通过withcontext
设置的 context 是线程安全的,参考会话获取详情
logger
也可以支持 context,可用于日志追踪。