GoFrame MongoDB 使用指南
GoFrame MongoDB 使用指南
1. 安装依赖
# 安装官方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 连接示例
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. 数据操作示例
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驱动:
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. 注意事项
- 使用官方MongoDB驱动
- 正确管理数据库连接
- 使用上下文(Context)控制超时
- 添加适当的错误处理
- 考虑连接池和性能优化
6. 复杂查询示例
// 复杂条件查询
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. 事务处理
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. 错误处理
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 操作方式,通过抽象层屏蔽了底层实现细节,使开发者可以专注于业务逻辑。