用Go语言借助mgo实现一个对MongoDB进行增删改查的demo
go version go1.11
MongoDB server version 4.0.3
背景
这是我第一次接触golang和MongoDB,正在在参照他们的官方手册学习。想试着用“测试驱动开发”(TDD)的模式来做这个demo。
写这个demo的目的是为了让自己开始写一些golang的代码,和练习一下MongoDB简单的CRUD操作。
准备
数据结构
这个demo以对一个简单的通讯录进行插入、查询、更新、删除记录为例,collection中包含name和phone两个字段:
{ name : "Jack_Green", phone : "9987650" }
下载mgo
MongoDB还没出官方的golang驱动包,mgo是现在比较流行的第三方包,能找到的相关资料也比较多。
go get gopkg.in/mgo.v2
开始
参照MongoDB官方手册在本地搭了一套环境,练习了在mongo shell中使用命令的CRUD操作,熟悉了一下这个数据库。
准备实现对MongoDB的增、删、改、查操作,先想了下怎么写测试案例。测试用了比较简单的方法来实现,而且没有考虑可能出现的全部情况,而是只写了各个操作的某一种情况。
编写测试案例
文件名 gomd_test.go可以自定义不同的db、collection名称,且测试时方便使对象统一修改,声明两个struct:
type Person struct { Name string Phone string } type Collection struct { DB string Name string }
在测试代码文件中声明两个变量:
var col = Collection{"testDB", "contacts"} var p = Person{"Jack_Green", "9987650"}
“C” 插入,测试插入方法,往通讯录中添加记录。不过要首先确保查询方法是可用的,我自己刚开始写的时候是先实现了查询方法,在插入之后,用查询方法把数据取出来打印。
// C create/insert func TestInsert(t *testing.T) { insert(p, col) pb := findByName(p.Name, col) if pb.Name != p.Name || pb.Phone != p.Phone { t.Error("insert failed") } fmt.Println("Insert Result") fmt.Println(pb) }
“R” 查找,通过name查找该条记录。
// R read/find func TestFindByName(t *testing.T) { p := findByName(p.Name, col) if p.Name == "" || p.Phone == "" { t.Error("find by name test failed") } fmt.Println("Find Result") fmt.Println(p) }
“U” 更新,修改通讯录中某位的手机号,根据name修改phone
// U update func TestUpdate(t *testing.T) { p := Person{"WEW", "121212122"} update(p, col) ub := findByName(p.Name, col) fmt.Println("Update Result") fmt.Println(ub) }
“D” 删除,根据name删除已存在的某条记录
// D delete func TestDeleteData(t *testing.T) { deleteData(p, col) }
golang代码实现对MongoDB的CRUD
文件名 godm.go刚刚开始写golang,对于创建session这部分有很多的冗余,等对它和mgo有了更深的了解之后,再来优化下。
导入必要的包
import ( "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "log" )
数据库地址
const ( URL = "127.0.0.1:27017" )
往通讯录中添加一条记录
func insert(p Person, col Collection) { session, err := mgo.Dial(URL) if err != nil { panic(err) } defer session.Close() c := session.DB(col.DB).C(col.Name) err = c.Insert(p) if err != nil { log.Fatal(err) } }
根据姓名从通讯录中查找联系方式
func findByName(name string, col Collection) Person { session, err := mgo.Dial(URL) if err != nil { panic(err) } defer session.Close() session.SetMode(mgo.Monotonic, true) collection := session.DB(col.DB).C(col.Name) result := Person{} err = collection.Find(bson.M{"name": name}).One(&result) if err != nil { log.Fatal(err) } return result }
更新通讯录中某人的联系方式
func update(p Person, col Collection) { session, err := mgo.Dial(URL) if err != nil { panic(err) } defer session.Close() collection := session.DB(col.DB).C(col.Name) err = collection.Update(bson.M{"name": p.Name}, bson.M{"$set": bson.M{"phone": p.Phone}}) if err != nil { log.Fatal(err) } }
将某人的信息从通讯录中删除
func deleteData(p Person, col Collection) { session, err := mgo.Dial(URL) if err != nil { panic(err) } defer session.Close() collection := session.DB(col.DB).C(col.Name) err = collection.Remove(bson.M{"name": p.Name}) }
测试结果
运行:
go test -v
输出:
=== RUN TestInsert Insert Result {Jack_Green 9987650} --- PASS: TestInsert (0.03s) === RUN TestFindByName Find Result {Jack_Green 9987650} --- PASS: TestFindByName (0.01s) === RUN TestUpdate Update Result {Jack_Green 121212122} --- PASS: TestUpdate (0.02s) === RUN TestDeleteData --- PASS: TestDeleteData (0.01s) PASS ok gomd 0.240s
附录
完整代码
Golang operation MongoDB demo : gomd