https://www.yuque.com/abs/dr4…
Using Store ????
Using Buckets
桶是键值对的集合。在一个桶中,键值唯一。
创建
使用 Tx.CreateBucket()
和 Tx.CreateBucketIfNotExists()
建立一个新桶(推荐使用第二个)
接受参数是 桶的名字
删除
使用 Tx.DeleteBucket()
根据桶的名字来删除
例子
func main() {db, err := bbolt.Open("./data", 0666, nil)
if err != nil {log.Fatal(err)
}
defer db.Close()
db.Update(func(tx *bbolt.Tx) error {b, err := tx.CreateBucketIfNotExists([]byte("MyBucket"))
if err != nil {return fmt.Errorf("create bucket: %v", err)
}
if err = tx.DeleteBucket([]byte("MyBucket")); err != nil {return err}
return nil
})
}
Using key/value pairs ????
最重要的部分,就是 kv 存储怎么使用了,首先需要一个 桶 来存储键值对。
Put
使用 Bucket.Put()
来存储键值对,接收两个 []byte
类型的参数
db.Update(func(tx *bolt.Tx) error {b := tx.Bucket([]byte("MyBucket"))
err := b.Put([]byte("answer"), []byte("42"))
return err
})
很明显,上面的例子设置了 Pair: key:answer value:42
Get
使用 Bucket.Get()
来查询键值。参数是一个 []byte
(别忘了这次我们只是查询,可以使用 只读事务)
db.View(func(tx *bolt.Tx) error {b := tx.Bucket([]byte("MyBucket"))
v := b.Get([]byte("answer"))
fmt.Printf("The answer is: %s\n", v)
return nil
})
细心会注意到,Get
是不会返回 error
的,这是因为 Get()
一定能正常工作(除非系统错误),相应的,当返回 nil
时,查询的键值对不存在。
⚠️:注意 0 长度的值 和 不存在键值对 的行为是不一样的。(一个返回是 nil,一个不是)
func main() {db, err := bolt.Open("./data.db", 0666, nil)
if err != nil {log.Fatal(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {b, err := tx.CreateBucketIfNotExists([]byte("MyBucket"))
if err != nil {return fmt.Errorf("create bucket: %v", err)
}
if err = b.Put([]byte("answer"), []byte("42")); err != nil {return err}
if err = b.Put([]byte("zero"), []byte("")); err != nil {return err}
return nil
})
db.View(func(tx *bolt.Tx) error {b := tx.Bucket([]byte("MyBucket"))
v := b.Get([]byte("noexists"))
fmt.Println(reflect.DeepEqual(v, nil)) // false
fmt.Println(v == nil) // true
v = b.Get([]byte("zero"))
fmt.Println(reflect.DeepEqual(v, nil)) // false
fmt.Println(v == nil) // true
return nil
})
}
Delete
使用 Bucket.Delete()
删除键值对
db.View(func(tx *bolt.Tx) error {b := tx.Bucket([]byte("MyBucket"))
fmt.Println(b.Get([]byte("answer")))
err := b.Delete([]byte("answer"))
if err != nil {return err}
return nil
})
⚠️:Get()
获取到的字节切片值只在当前事务(当前函数作用域)有效,如果要在其他事务中使用需要使用 copy()
将其拷贝到其他的字节切片