使用数据库MongoDB
创建web应用,数据持久化是非常重要的.可以使用Go的结构体来定义数据模型,对应保存的程序数据.
- 关于MongoDB
MongoDB作为非关系型数据库在web应用开发中的应用非常流行.MongoDB是开源的数据库,有着高效,友好,自动伸缩的特点.MongoDB作为非关系型数据库,保存的数据都是二进制的文档,称为 BSON Binary(BSON).简单的说,MongoDB把数据保存为BSON文档.Go的结构体可以容易的序列化为BSON文档.了解更多,可以查看官方文档. www.mongodb.org/ .
MongoDB数据库持有多个文档的集合.一个文档有一个或者多个字段,就是保存的数据key-value集合.在MongoDB,documents保存在collections中,类似在关系型数据库table保存在database中,documents类似rows,在document中的field类似columns.
和关系型数据库不同的是,MongoDB 有着更加灵活的方式操作documents,无论何时对象模型在展开,都可以修改.在Go当中使用MongoDB.Go的结构体就是document的结构,你可以任何时候修改这个结构,如果程序的数据结构改变.在一个collection的document不需要有相同的字段或者结构,相同的字段可以保存不同的数据类型.这样的动态结构在迭代开发应用的时候非常有用.
- 开始使用MongoDB
安装MongoDB: Mac下使用Homebrew安装非常简单.
在使用MongoDB前确保开启了MongoDB服务.
驱动:mgo go get gopkg.in/mgo.v2
链接MongoDB:
session, err := mgo.Dial("localhost")
Dial方法也可以用来链接服务器集群,在将MongoDB集合到服务器群中非常有用.
session, err := mgo.Dial("server1.mongolab.com,server2.mongolab.com")
还可以使用DialWithInfo方法链接服务器或者服务器群.不同的是DialWithInfo方法可以提供额外的值给服务器. DialWithInfo和服务器(群)建立一个新的session. DialWithInfo方法也可以自定义值,当链接服务器的时候. 当使用Dial方法建立链接,默认的超时时间为10秒,使用DialWithInfo可以自己设置超时时间.
mongoDialInfo := &mgo.DialInfo{
Addrs:[]string{"localhost"},
Timeout:60 * time.Second,
Database:"taskdb",
Username:"xiaoming",
Password:"123456"
}
session,err := mgo.DialWithInfo(mongoDialInfo)
mgo.Session 对象持有一个MongoDB的链接池子,一旦获取到一个Session对象就可以进行读取操作.
- 访问collections
在MongoDB进行CRUD操作,一个 *mgo.Collection 对象被创建,对应了MongoDB的collection.调用 mgo.Database的方法C创建mgo.Collection对象. *mgo.Database对象可以通过 *mgo.Session 的DB方法创建.
//访问一个Collection
c := session.DB("taskdb").C("categories")
- MongoDB的CRUD
在Go,可以将struct,map,slice转换为BSON 保存在MongoDB数据库.mgo驱动会自动把这些数据类型序列换为BSON文档.
使用 mgo.Collection 的Insert方法插入一个document,Insert方法可以插入一个或者多个document到collection,使用这个方法,可以插入struct,map,slice值.
一个插入struct值的例子
// mongodb
package main
import (
"fmt"
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Category struct {
Id bson.ObjectId `bson:"_id,omitempty"`
Name string
Description string
}
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
//获取一个集合
c := session.DB("taskdb").C("categories")
doc := Category{
bson.NewObjectId(),
"Open Source",
"Tasks for open-source projects",
}
//插入一个模型对象
err = c.Insert(&doc)
if err != nil {
log.Fatal(err)
}
//插入两个模型对象
err = c.Insert(&Category{bson.NewObjectId(), "R & D", "R & D Tasks"}, &Category{bson.NewObjectId(), "Project", "Project Tasks"})
var count int
count, err = c.Count()
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("%d records inserted", count)
}
}
运行之后的数据库数据:

数据模型Category结构体的数据将会被保存到MongoDB数据库. 指定_id字段是bson.ObjectId类型,ObjectId是一个12字节的BSON类型,是一个唯一值. BSON document保存到collection中时需要一个唯一的id值作为基本的key.当插入一个记录到MongoDBcollection,可以调用bson.NewObjectId()方法产生一个唯一的值.当mgo序列号数据的时候,会把_id字段插入,如果没有就会自动产生一个.
mgo.Collection的Insert方法通常用来把数据持久化到数据库,在这个例子,一个名为"categories"的Collection调用Insert方法插入数据到collection.
在这个例子,三个document被插入,Count方法用来获取到collection的记录.第一次运行程序,控制台输出为:3 records inserted
- 插入 map到数据库
// mongodb
package main
import (
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
//获取一个集合
c := session.DB("taskdb").C("categories")
docM := map[string]string{
"name": "Open Source",
"description": "Tasks for open-source projects",
}
//插入一个Map
err = c.Insert(docM)
if err != nil {
log.Fatal(err)
}
docD := bson.D{
{"name", "Project"},
{"description", "Project Tasks"},
}
//插入一个Slice
err = c.Insert(docD)
if err != nil {
log.Fatal(err)
}
}
//运行后,数据库增加了两条数据

使用map,slice对象插入到collection. bson.D类型 表现为一个BSON document.Insert方法的参数是一个interface{},所以struct,map,sclice都可以作为参数.
来了就领一个红包再走吧.

网友评论
2,官网是这么解释的,MongoDB stores documents in collections. Collections are analogous to tables in relational databases.
也就是说,collection相当于表