//根据礼物id列表查询指定的礼物
func GetGiftListByIds(gift_ids []int64,projection bson.M)(list []models.LuGiftList,err error){
cur, err := mongo_coll(gift_table).Find(ctx, bson.M{"status":1,"_id":bson.M{"$in":gift_ids}},options.Find().SetProjection(projection))
defer func(){
cur.Close(ctx)
}()
if err != nil {
return
}
err = IterateCursor(cur,&list)
return
}
func UserBusinessStreamerList(req *iapi.UserBusinessStreamerListReq)(list []models.LuUserInfo,count int64,err error){
filter := bson.M{"flag":types.USER_STREAMER,"p_staff":(*req).BusinessId}
if (*req).StreamerId !=0{
filter["_id"] = (*req).StreamerId
}
if len((*req).StreamerName) != 0{
filter["nick_name"] = bson.M{"$regex":(*req).StreamerName}
}
count,err = mongo_coll_count(mongo_coll,user_table,filter)
if err != nil{
return
}
if count < 1{
return
}
skip := int64(int64((*req).Page - 1) * int64((*req).PageSize))
find_options := options.Find().SetSkip(skip).SetLimit(int64((*req).PageSize))
sort_option := options.Find().SetSort(bson.D{{"_id", -1}})
cur, err := mongo_coll(user_table).Find(ctx, filter,find_options,sort_option)
defer func(){
cur.Close(ctx)
}()
if err != nil {
return
}
list,err = user_info_range_list_comm(ctx,cur)
return
}
GetGiftListByIds、UserBusinessStreamerList都有执行如下函数
defer func(){
cur.Close(ctx)
}()
我想封装一个通用的函数,在函数执行完后自动执行
defer func(){
cur.Close(ctx)
}
golang封装mongo查询完统一关闭资源
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
5条回答 默认 最新
檀越@新空间 2025-10-01 21:24关注晚上好🌙🌙🌙
本答案参考通义千问为了实现统一关闭MongoDB查询资源的功能,我们可以将
cur.Close(ctx)的逻辑封装到一个通用函数中,这样可以避免在多个函数中重复编写defer cur.Close(ctx)代码。这种方式不仅提高了代码的可维护性,也减少了出错的可能性。
✅ 一、目标
- 封装一个通用函数,在执行完MongoDB查询后自动关闭游标(
cur)。 - 确保所有使用该函数的调用者都能正确关闭资源。
- 提供清晰的结构和示例代码。
✅ 二、解决方案
1. 创建通用的MongoDB查询函数
我们定义一个通用的函数
QueryWithCursor,它接收查询条件、投影、排序等参数,并返回游标和错误。同时,在函数内部使用defer cur.Close(ctx)来确保资源被释放。func QueryWithCursor( ctx context.Context, collectionName string, filter bson.M, opts ...*options.FindOptions, ) (*mongo.Cursor, error) { coll := mongo_client.Database("your_db_name").Collection(collectionName) cur, err := coll.Find(ctx, filter, opts...) if err != nil { return nil, err } // 自动关闭游标 defer func() { cur.Close(ctx) }() return cur, nil }注意: 需要根据实际数据库配置初始化
mongo_client。
2. 使用封装后的通用函数修改原有函数
修改
GetGiftListByIdsfunc GetGiftListByIds(gift_ids []int64, projection bson.M) (list []models.LuGiftList, err error) { filter := bson.M{"status": 1, "_id": bson.M{"$in": gift_ids}} opts := options.Find().SetProjection(projection) cur, err := QueryWithCursor(ctx, gift_table, filter, opts) if err != nil { return nil, err } err = IterateCursor(cur, &list) return list, err }修改
UserBusinessStreamerListfunc UserBusinessStreamerList(req *iapi.UserBusinessStreamerListReq) (list []models.LuUserInfo, count int64, err error) { filter := bson.M{"flag": types.USER_STREAMER, "p_staff": (*req).BusinessId} if (*req).StreamerId != 0 { filter["_id"] = (*req).StreamerId } if len((*req).StreamerName) != 0 { filter["nick_name"] = bson.M{"$regex": (*req).StreamerName} } count, err = mongo_coll_count(mongo_coll, user_table, filter) if err != nil { return } if count < 1 { return } skip := int64(((*req).Page - 1) * (*req).PageSize) findOptions := options.Find().SetSkip(skip).SetLimit(int64((*req).PageSize)) sortOptions := options.Find().SetSort(bson.D{{"_id", -1}}) cur, err := QueryWithCursor(ctx, user_table, filter, findOptions, sortOptions) if err != nil { return } list, err = user_info_range_list_comm(ctx, cur) return }
✅ 三、关键点总结
-
通用函数封装:
QueryWithCursor是一个封装好的函数,用于执行MongoDB查询并自动关闭游标。- 它接受上下文、集合名、过滤条件以及查询选项。
-
资源管理:
- 在
QueryWithCursor中使用defer cur.Close(ctx)确保资源及时释放。 - 这样即使发生错误或提前返回,也能保证资源不会泄漏。
- 在
-
代码复用:
- 所有需要查询MongoDB的函数都可以使用这个通用函数,避免重复代码。
- 提高了代码的可读性和可维护性。
✅ 四、注意事项
- 确保
mongo_client已经正确初始化。 - 如果使用了多个数据库或集合,建议进一步抽象为
Database或Collection的参数。 - 如果你使用的是 Go 模块,请确保导入正确的 MongoDB 包(如
go.mongodb.org/mongo-driver/mongo)。
✅ 五、完整示例代码(可直接使用)
package main import ( "context" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var mongo_client *mongo.Client var ctx context.Context func init() { // 初始化 MongoDB 客户端 clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") var err error mongo_client, err = mongo.Connect(ctx, clientOptions) if err != nil { panic(err) } } func QueryWithCursor( ctx context.Context, collectionName string, filter bson.M, opts ...*options.FindOptions, ) (*mongo.Cursor, error) { coll := mongo_client.Database("your_db_name").Collection(collectionName) cur, err := coll.Find(ctx, filter, opts...) if err != nil { return nil, err } defer func() { cur.Close(ctx) }() return cur, nil }
如果你还有其他业务逻辑需要封装,也可以继续扩展这个通用函数,例如支持分页、聚合查询等。欢迎继续提问!
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 封装一个通用函数,在执行完MongoDB查询后自动关闭游标(