boltdb 基础使用

 阅读约 6 分钟

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() 将其拷贝到其他的字节切片

阅读 129发布于 10月1日
推荐阅读
目录