用Go語言藉助mgo實現一個對MongoDB進行增刪改查的demo

環境聲明:
go version go1.11
MongoDB server version 4.0.3

背景

這是我第一次接觸golang和MongoDB,正在在參照他們的官方手冊學習。想試着用「測試驅動開發」(TDD)的模式來作這個demo。git

寫這個demo的目的是爲了讓本身開始寫一些golang的代碼,和練習一下MongoDB簡單的CRUD操做。github

準備

數據結構

這個demo以對一個簡單的通信錄進行插入、查詢、更新、刪除記錄爲例,collection中包含name和phone兩個字段:golang

{ name : "Jack_Green", phone : "9987650" }

下載mgo

MongoDB還沒出官方的golang驅動包,mgo是如今比較流行的第三方包,能找到的相關資料也比較多。mongodb

go get gopkg.in/mgo.v2

開始

參照MongoDB官方手冊在本地搭了一套環境,練習了在mongo shell中使用命令的CRUD操做,熟悉了一下這個數據庫。shell

準備實現對MongoDB的增、刪、改、查操做,先想了下怎麼寫測試案例。測試用了比較簡單的方法來實現,並且沒有考慮可能出現的所有狀況,而是隻寫了各個操做的某一種狀況。數據庫

編寫測試案例

文件名 gomd_test.go

能夠自定義不一樣的db、collection名稱,且測試時方便使對象統一修改,聲明兩個struct:session

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

參考資料

Golang鏈接MongoDB數據庫

How To Build Microservice With MongoDB In Golang

godoc : labix mgo v2

相關文章
相關標籤/搜索