bolt简介
bolt数据库是一个纯GO语言 实现的键值对数据库 ,支持完全的ACID事务操作.
bolt库通过使用一个内存映射的磁盘文件来管理数据,逻辑清晰,接口简单易用;
相比于使用数据库连接工具类的东西比如mysql、SQlite来操作数据持久化,而是通过一个文件(bucket)来存储数据,虽然访问不够灵活,但是效率比较高,所以可以考虑用bolt库来进行测试
bolt安装 1 go get github.com/boltdb/bolt
bolt使用 ###操作打开以及关闭Bolt库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //定义db文件名常量 const dbFile="my.db" //需要使用到的函数:func Open(path string, mode os.FileMode, options *Options) (*DB, error) //Open函数接受三个参数: //第一个参数表示bucket路径,第二个参数表示操作方式,第三个参数表示配置信息,没有明确可以不配置,直接写nil //打开.db文件,如果不存在则创建,如果存在则打开 db,err := bolt.Open(dbFile,0666,nil) //错误处理 if err != nil { log.Fatal("db文件查找或创建失败,请稍后重试") } //关闭 defer db.Close()
Transaction(事务) Bolt数据库同时只支持一个read-write transaction或者多个read-only transaction,一般来说read-only的transaction和read-write transaction不应该相互之间有依赖,即同一个goroutinr中不要同时打开这两种transaction–>(可能会出现死锁的情况) Read-write transactions(读写事务) 通过DB.Update打开一个read-write transaction:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //定义bucketName常量 const bucketName="bucket01" //db为上面通过Open()函数(打开文件)获取的操作对象 if err:=db.Update(func(tx *bolt.Tx) error){ // CreateBucket() creates a new bucket.(bucket中的所有key必须是唯一的) //在Update事务中可以更改操作(创建bucket,修改bucket中某个键的值等等) if _, err = tx.CreateBucket([]byte("bucketName")); err != nil { logger.Log("create failed", err) return err } return nil });;err!=nil{ log.panic(err) }
Read-Only transactions(只读事务) 1 2 3 4 5 6 7 8 9 10 if err := db.View(func(tx *bolt.Tx) error { // if _, err := tx.CreateBucket([]byte("bucketName")); err != nil { // logger.Log("create failed", err) // return err // } return nil }); err != nil { log.panic(err) }
View()中不允许更改操作,只能获取bucket,查询value,复制数据库,所以上面注释代码加上会报错
使用key/value 将一个key/value保存到bucket中**(保存在bucket中的键值对是无序的)**,使用Bucket.Put()函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 if err:=db.Update(func(tx *bolt.Tx) error){ b:=tx.Bucket([]byte(bucketName)) //Put sets the value for a key in the bucket. //需要传入两个字节数组,第一个字节数组作为key值,第二个字节数组作为对应key值的value值 err=b.Put([]byte("1"),[]byte(""block01)) return err //return nil });err!=nil{ logger.Log("update",err) }
上面代码的”1”->”block01” key-value对保存到bucket “bucket01”中,可以使用Bucket.Get()函数获取”block01”这个值
1 2 3 4 5 6 7 8 9 10 11 12 13 if err:=db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("bucketName")) //Get retrieves the value for a key in the bucket. //需要一个传入类型为字节数组的"key"值 v := b.Get([]byte("1")) fmt.Printf("the anser is :%s\n", v) return nil }); err != nil { logger.Log("view", err) } }
最后附上一张图说明.db文件和bucket的关系: