总的来说,boltDB 适用于内存 > 数据库,读 > 写,稳定 > 性能 的场合
Linux 环境下
go get github.com/boltdb/bolt
Windows 环境
import (
"github.com/boltdb/bolt"
)
使用 BoltDB 的样例
package main
import (
"log"
"github.com/boltdb/bolt"
)
func main() {
db, err := bolt.Open("my.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
...
}
err := db.Update(func(tx *bolt.Tx) error {
...
return nil
})
err := db.View(func(tx *bolt.Tx) error {
...
return nil
})
以创建一个包含 Article 和 User 的博客网站数据库为例
将对数据库的访问操作,封装成函数存放在 db.go 文件
//get the database absolute path
func DBPATH() string {
pt, _ := os.Getwd()
fmt.Println(path.Join(pt ,"/source/Blog.db"))
return path.Join(pt ,"/source/Blog.db")
}
//create the bucket for article and user
func Init() {
db, err := bolt.Open(DBPATH(), 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("article"))
if b == nil {
_, err := tx.CreateBucket([]byte("article"))
if err != nil {
log.Fatal(err)
}
}
b = tx.Bucket([]byte("user"))
if b == nil {
_, err := tx.CreateBucket([]byte("user"))
if err != nil {
log.Fatal(err)
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
}
打开数据库
获取一个事务 tx
根据 tx 获取bucket b
进行更新——b.Put(key, data)
进行查询——b.Get(key)
下面以 Articles 和 Users 为例
// PutArticle : put one article to blog.db
func PutArticle(article Article) error {
db, err := bolt.Open(DBPATH(), 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("article"))
if b != nil {
key := make([]byte, 8)
binary.LittleEndian.PutUint64(key, uint64(article.Id))
data, _ := json.Marshal(article)
b.Put(key, data)
}
return nil
})
if err != nil {
return err
}
return nil
}
func PutUser(user User) error {
db, err := bolt.Open(DBPATH(), 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("user"))
if b != nil {
data, _ := json.Marshal(user)
b.Put([]byte(user.Username), data)
}
return nil
})
if err != nil {
return err
}
return nil
}
// Get Atricle with ID,ID=-1 means get all articles
func GetArticles(id int64, page int64) []Article {
db, err := bolt.Open(DBPATH(), 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
articles := make([]Article, 0)
err = db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("article"))
if b != nil && id >= 0 {
key := make([]byte, 8)
binary.LittleEndian.PutUint64(key, uint64(id))
data := b.Get(key)
if data != nil {
atc := Article{}
err := json.Unmarshal(data, &atc)
if err != nil {
log.Fatal(err)
}
articles = append(articles, atc)
}
} else if b != nil && id == -1 {
cursor := b.Cursor()
nPerPage := 5
fromKey := make([]byte, 8)
binary.LittleEndian.PutUint64(fromKey, uint64(page-1)*(uint64)(nPerPage+1))
for k, v := cursor.Seek(fromKey); k != nil && nPerPage > 0; k, v = cursor.Next() {
atc := Article{}
err := json.Unmarshal(v, &atc)
if err != nil {
log.Fatal(err)
}
articles = append(articles, atc)
nPerPage--
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
return articles
}
//Get user information with the username
func GetUser(username string) User {
db, err := bolt.Open(DBPATH(), 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
user := User{}
err = db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("user"))
if b != nil {
data := b.Get([]byte(username))
if data != nil {
err := json.Unmarshal(data, &user)
if err != nil {
log.Fatal(err)
}
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
return user
}
func writeOneBlog(id int64,title string,author string,tags []db.Tag,date string,content string,comments []db.Comment){
articles := db.Article{id,title,author,tags,date,content,comments}
users := db.User{author,author}
db.PutArticle(articles)
db.PutUser(users)
}