GoFrame MongoDB 使用指南

GoFrame MongoDB 使用指南

1. 安装依赖

bash 复制代码
# 安装官方MongoDB驱动
go get -u go.mongodb.org/mongo-driver/mongo
go get -u go.mongodb.org/mongo-driver/mongo/options
go get -u go.mongodb.org/mongo-driver/bson

2. MongoDB 连接示例

go 复制代码
package main

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func ConnectMongoDB() (*mongo.Client, error) {
    // 设置客户端连接配置
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // 设置连接超时
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // 连接到MongoDB
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        return nil, err
    }

    // 验证连接
    err = client.Ping(ctx, nil)
    if err != nil {
        return nil, err
    }

    return client, nil
}

3. 数据操作示例

go 复制代码
package main

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct {
    ID       string    `bson:"_id,omitempty"`
    Username string    `bson:"username"`
    Email    string    `bson:"email"`
    Age      int       `bson:"age"`
    CreateAt time.Time `bson:"create_at"`
}

// 插入数据
func InsertUser(client *mongo.Client, user User) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.InsertOne(context.Background(), user)
    return err
}

// 查询数据
func FindUserByUsername(client *mongo.Client, username string) (*User, error) {
    collection := client.Database("testdb").Collection("users")
    
    var user User
    err := collection.FindOne(context.Background(), bson.M{"username": username}).Decode(&user)
    if err != nil {
        return nil, err
    }
    
    return &user, nil
}

// 更新数据
func UpdateUser(client *mongo.Client, username string, update bson.M) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.UpdateOne(
        context.Background(), 
        bson.M{"username": username},
        bson.M{"$set": update},
    )
    return err
}

// 删除数据
func DeleteUser(client *mongo.Client, username string) error {
    collection := client.Database("testdb").Collection("users")
    
    _, err := collection.DeleteOne(context.Background(), bson.M{"username": username})
    return err
}

// 复杂查询
func ComplexQuery(client *mongo.Client) ([]User, error) {
    collection := client.Database("testdb").Collection("users")
    
    // 查询年龄大于18的用户
    cursor, err := collection.Find(context.Background(), bson.M{
        "age": bson.M{"$gt": 18},
    })
    if err != nil {
        return nil, err
    }
    defer cursor.Close(context.Background())

    var users []User
    if err = cursor.All(context.Background(), &users); err != nil {
        return nil, err
    }

    return users, nil
}

4. 与GoFrame集成

虽然GoFrame的gdb不直接支持MongoDB,但你可以在GoFrame应用中使用官方MongoDB驱动:

go 复制代码
package service

import (
    "github.com/gogf/gf/v2/frame/g"
    "go.mongodb.org/mongo-driver/mongo"
)

type MongoService struct {
    client *mongo.Client
}

func (s *MongoService) Init() error {
    client, err := ConnectMongoDB()
    if err != nil {
        g.Log().Error(context.Background(), "MongoDB连接失败:", err)
        return err
    }
    s.client = client
    return nil
}

func (s *MongoService) GetCollection(dbName, collectionName string) *mongo.Collection {
    return s.client.Database(dbName).Collection(collectionName)
}

5. 注意事项

  1. 使用官方MongoDB驱动
  2. 正确管理数据库连接
  3. 使用上下文(Context)控制超时
  4. 添加适当的错误处理
  5. 考虑连接池和性能优化

6. 复杂查询示例

go 复制代码
// 复杂条件查询
func ComplexQuery(ctx context.Context) {
    // 年龄大于18且邮箱域名为gmail的用户
    users, err := g.Model("users").Ctx(ctx).
        Where("age", ">", 18).
        WhereLike("email", "%@gmail.com").
        Order("create_at DESC").
        Limit(10).
        All()
    
    // 聚合查询
    result, err := g.Model("users").Ctx(ctx).
        Fields("age", "COUNT(*) as count").
        Group("age").
        Having("count > 5").
        All()
}

7. 事务处理

go 复制代码
func TransactionExample(ctx context.Context) error {
    return g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
        // 执行多个数据库操作
        _, err1 := tx.Model("users").Data(g.Map{
            "username": "newuser",
            "email":    "newuser@example.com",
        }).Insert()

        _, err2 := tx.Model("logs").Data(g.Map{
            "action": "user_created",
        }).Insert()

        // 任何一个操作失败都会回滚
        if err1 != nil || err2 != nil {
            return errors.New("transaction failed")
        }
        return nil
    })
}

8. 性能优化建议

  • 使用索引
  • 避免返回大量数据
  • 使用投影减少网络传输
  • 合理使用缓存

9. 错误处理

go 复制代码
func ErrorHandling(ctx context.Context) {
    user, err := dao.User.FindByUsername(ctx, "example")
    if err != nil {
        switch {
        case err == g.ErrRecordNotFound:
            // 处理未找到记录
            g.Log().Error(ctx, "User not found")
        case g.IsDBError(err):
            // 处理数据库错误
            g.Log().Error(ctx, "Database error:", err)
        default:
            // 其他未知错误
            g.Log().Error(ctx, "Unexpected error:", err)
        }
    }
}

总结

GoFrame 提供了强大且简洁的 MongoDB 操作方式,通过抽象层屏蔽了底层实现细节,使开发者可以专注于业务逻辑。

相关推荐
赵渝强老师2 小时前
【赵渝强老师】PostgreSQL中表的碎片
数据库·postgresql
全栈老石6 小时前
拆解低代码引擎核心:元数据驱动的"万能表"架构
数据库·低代码
倔强的石头_1 天前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
AI全栈实验室4 天前
MongoDB迁移金仓踩了5个坑,最后一个差点回滚
mongodb
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号35 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏5 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker