Go 封装 mongo

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: Go 封装 mongo

一、封装代码

package mongodb
import (
  "context"
  "log"
  "go.mongodb.org/mongo-driver/bson"
  "go.mongodb.org/mongo-driver/bson/primitive"
  "go.mongodb.org/mongo-driver/mongo"
  "go.mongodb.org/mongo-driver/mongo/options"
)
var client *mongo.Client
func NewMongoDB(ctx context.Context, appUri string) error {
  //连接到mongodb
  c, err := mongo.Connect(ctx, options.Client().ApplyURI(appUri))
  if err != nil {
    return err
  }
  //检查连接
  err = c.Ping(ctx, nil)
  if err != nil {
    return err
  }
  client = c
  log.Println("mongodb连接成功")
  return nil
}
type MongoDB[T any] struct {
  database   string
  collection string
}
func NewMGDB[T any](database string, collection string) *MongoDB[T] {
  if client == nil {
    log.Fatalln("mongo.Client Not initialized !")
  }
  return &MongoDB[T]{
    database,
    collection,
  }
}
//新增一条记录
func (mg *MongoDB[T]) InsertOne(ctx context.Context, value T) *mongo.InsertOneResult {
  result, err := mg.getCollection().InsertOne(ctx, value)
  if err != nil {
    panic(err)
  }
  return result
}
//新增多条记录
func (mg *MongoDB[T]) InsertMultiple(ctx context.Context, data []T) *mongo.InsertManyResult {
  var array []interface{}
  for i := 0; i < len(data); i++ {
    array = append(array, data[i])
  }
  result, err := mg.getCollection().InsertMany(ctx, array)
  if err != nil {
    panic(err)
  }
  return result
}
//根据字段名和值查询一条记录
func (mg *MongoDB[T]) FindOne(ctx context.Context, filter filter) (T, error) {
  var t T
  err := mg.getCollection().FindOne(ctx, filter).Decode(&t)
  if err != nil {
    return t, err
  }
  return t, nil
}
//根据条件查询多条记录
func (mg *MongoDB[T]) Find(ctx context.Context, filter filter, limit int64) ([]T, error) {
  findOpts := options.Find()
  findOpts.SetLimit(limit)
  cursor, err := mg.getCollection().Find(ctx, filter, findOpts)
  var ts []T
  if err != nil {
    return ts, err
  }
  for cursor.Next(ctx) {
    var t T
    err := cursor.Decode(&t)
    if err != nil {
      return ts, err
    }
    ts = append(ts, t)
  }
  cursor.Close(ctx)
  return ts, nil
}
//根据条件更新
func (mg *MongoDB[T]) UpdateOne(ctx context.Context, filter filter, update interface{}) (int64, error) {
  result, err := mg.getCollection().UpdateOne(ctx, filter, bson.M{"$set": update})
  return result.ModifiedCount, err
}
//根据id更新
func (mg *MongoDB[T]) UpdateOneById(ctx context.Context, id string, update interface{}) (int64, error) {
  result, err := mg.getCollection().UpdateOne(ctx, filter{{Key: "_id", Value: mg.ObjectID(id)}}, update)
  return result.ModifiedCount, err
}
//更新多个
func (mg *MongoDB[T]) UpdateMany(ctx context.Context, filter filter, update interface{}) (int64, error) {
  result, err := mg.getCollection().UpdateMany(ctx, filter, bson.D{{Key: "$set", Value: update}})
  return result.ModifiedCount, err
}
//获取表
func (mg *MongoDB[T]) getCollection() *mongo.Collection {
  return client.Database(mg.database).Collection(mg.collection)
}
//删除一条记录
func (mg *MongoDB[T]) DeleteOne(ctx context.Context, filter filter) (int64, error) {
  result, err := mg.getCollection().DeleteOne(ctx, filter)
  return result.DeletedCount, err
}
//根据id删除一条记录
func (mg *MongoDB[T]) DeleteOneById(ctx context.Context, id string) (int64, error) {
  result, err := mg.getCollection().DeleteOne(ctx, filter{{Key: "_id", Value: mg.ObjectID(id)}})
  return result.DeletedCount, err
}
//删除多条记录
func (mg *MongoDB[T]) DeleteMany(ctx context.Context, filter filter) (int64, error) {
  result, err := mg.getCollection().DeleteMany(ctx, filter)
  return result.DeletedCount, err
}
//objcetid
func (mg *MongoDB[T]) ObjectID(id string) primitive.ObjectID {
  objectId, err := primitive.ObjectIDFromHex(id)
  if err != nil {
    log.Fatal(err)
  }
  return objectId
}
//定义过滤器
type filter bson.D
//匹配字段值大于指定值的文档
func (f filter) GT(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$gt", Value: value}}})
  return f
}
//匹配字段值大于等于指定值的文档
func (f filter) GTE(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$gte", Value: value}}})
  return f
}
//匹配字段值等于指定值的文档
func (f filter) EQ(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$eq", Value: value}}})
  return f
}
//匹配字段值小于指定值的文档
func (f filter) LT(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$lt", Value: value}}})
  return f
}
//匹配字段值小于等于指定值的文档
func (f filter) LET(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$let", Value: value}}})
  return f
}
//匹配字段值不等于指定值的文档,包括没有这个字段的文档
func (f filter) NE(key string, value interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$ne", Value: value}}})
  return f
}
//匹配字段值等于指定数组中的任何值
func (f filter) IN(key string, value ...interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$in", Value: value}}})
  return f
}
//字段值不在指定数组或者不存在
func (f filter) NIN(key string, value ...interface{}) filter {
  f = append(f, bson.E{Key: key, Value: bson.D{{Key: "$nin", Value: value}}})
  return f
}
//创建一个条件查询对象
func Newfilter() filter {
  return filter{}
}

二、测试代码

type Test struct {
  Id            primitive.ObjectID `bson:"_id"`
  Title         string             `bson:"title"`
  Author        string             `bson:"author"`
  YearPublished int64              `bson:"year_published"`
}
func main() {
  ctx := context.Background()
  //连接数据库
  err := mongodb.NewMongoDB(ctx, "mongodb://localhost:27017")
  if err != nil {
    log.Fatalf("%s", err)
    return
  }
  //设置使用的库和表
  mgdb := mongodb.NewMGDB[Test]("test", "favorite_books")
  //插入单条
  insertOneResult := mgdb.InsertOne(ctx, Test{
    Id:            primitive.NewObjectID(),
    Title:         "test",
    Author:        "author test",
    YearPublished: 9999,
  })
  log.Printf("插入单条记录: %v \n", insertOneResult.InsertedID)
  //插入多条
  var tests []Test
  for i := 1; i < 100; i++ {
    tests = append(tests, Test{
      Id:            primitive.NewObjectID(),
      Title:         "test_" + fmt.Sprintf("%d", i),
      Author:        "author test " + fmt.Sprintf("%d", i),
      YearPublished: int64(i),
    })
  }
  insertMultipleResult := mgdb.InsertMultiple(ctx, tests)
  log.Printf("插入多条记录: %v \n", insertMultipleResult.InsertedIDs)
  //查询
  filter := mongodb.Newfilter().EQ("title", "test").EQ("author", "author test")
  result, err := mgdb.FindOne(ctx, filter)
  if err != nil {
    log.Fatalf("%s", err)
  }
  buf, err := json.Marshal(result)
  fmt.Printf("查询单条记录: %s\n  ", string(buf))
  //查询
  filter = mongodb.Newfilter().GT("year_published", 5).LT("year_published", 10)
  results, err := mgdb.Find(ctx, filter, 10)
  if err != nil {
    log.Fatalf("%s", err)
  }
  buf, err = json.Marshal(results)
  fmt.Printf("查询多条记录: %v\n  ", string(buf))
  //单条记录更新
  filter = mongodb.Newfilter().EQ("year_published", 9999)
  updateCount, err := mgdb.UpdateOne(ctx, filter, map[string]interface{}{
    "author": "test 00021",
  })
  if err != nil {
    log.Fatalf("%s", err)
  }
  fmt.Printf("更新数量 : %d\n", updateCount)
  //批量更新
  filter = mongodb.Newfilter().IN("year_published", 11, 12, 13)
  updateCount, err = mgdb.UpdateMany(ctx, filter, map[string]interface{}{
    "author": "update author",
  })
  if err != nil {
    log.Fatalf("%s", err)
  }
  fmt.Printf("批量更新数量 : %d\n", updateCount)
  //单条数据删除
  filter = mongodb.Newfilter().EQ("year_published", 15)
  deleteCount, err := mgdb.DeleteOne(ctx, filter)
  if err != nil {
    log.Fatalf("%s", err)
  }
  fmt.Printf("单条数据删除数量 : %d\n", deleteCount)
  //多条数据删除
  filter = mongodb.Newfilter().IN("year_published", 16, 17, 18)
  deleteCount, err = mgdb.DeleteMany(ctx, filter)
  if err != nil {
    log.Fatalf("%s", err)
  }
  fmt.Printf("多条数据删除数量 : %d\n", deleteCount)
}
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
5月前
|
Go 开发者
掌握Go语言:Go语言结构体,精准封装数据,高效管理实体对象(22)
掌握Go语言:Go语言结构体,精准封装数据,高效管理实体对象(22)
|
12月前
|
安全 Go
Go语言封装艺术:代码安全与结构清晰
Go语言封装艺术:代码安全与结构清晰
76 0
|
4月前
|
存储 中间件 Go
在go语言服务中封装路由和示例
【6月更文挑战第23天】本文介绍golang后端按协议处理、中间件(一次性与每次请求执行)划分、以及服务架构Controller、Logic/Service、DAO/Repository和Routers划分。代码仓库在GitHub上提供。使用框架简化了交互和处理。后续章节深入探讨服务构建。
153 5
在go语言服务中封装路由和示例
|
2月前
|
编译器 Go
Go语言中的闭包:封装数据与功能的强大工具
Go语言中的闭包:封装数据与功能的强大工具
|
2月前
|
Ubuntu Go Docker
[go]封装go的docker镜像
[go]封装go的docker镜像
|
5月前
|
Go
Go 定时任务方法封装
Go 定时任务方法封装
47 0
|
12月前
|
SQL 安全 中间件
Go开发:如何封装函数来统计执行时间
Go开发:如何封装函数来统计执行时间
376 0
|
Go
Go 封装 mongo
Go 封装 mongo
200 0
|
Go
Go 定时任务方法封装
Go 定时任务方法封装
82 0
|
Go 数据格式 JSON
Go语言封装Http协议GET和POST请求
本文几乎没有文字叙述:   /* 有关Http协议GET和POST请求的封装 */ package net import ( "net/http" "io" "bytes" "encoding/json" "io/ioutil" ...
4000 0