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 操作方式,通过抽象层屏蔽了底层实现细节,使开发者可以专注于业务逻辑。

相关推荐
SAP小崔说事儿1 小时前
在数据库中将字符串拆分成表单(SQL和HANA版本)
java·数据库·sql·sap·hana·字符串拆分·无锡sap
川贝枇杷膏cbppg2 小时前
asmcmd
数据库·oracle
JIngJaneIL2 小时前
基于java+ vue助农电商系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
IndulgeCui2 小时前
基于CentOS7 DM8单机部署配置记录-20251216
数据库
surtr12 小时前
关系代数与关系型数据库
数据库·sql·数据库系统
学海_无涯_苦作舟3 小时前
MySQL面试题
数据库·mysql·面试
老邓计算机毕设3 小时前
SSM校内二手书籍交易系统的设计与实现an1k0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·ssm 框架开发·ssm 校内二手书籍交易系统
天行健,君子而铎4 小时前
高性能、可控、多架构:教育行业数据库风险监测一体化解决方案
数据库·架构
Stella25214 小时前
实习日志|知识总结
linux·服务器·软件测试·数据库