分享
  1. 首页
  2. 文章

Golang使用LMDB

clawhub · · 1585 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

lmdb的相关简介可以看我的其他博客,这里记录go简单使用lmdb。我使用了https://github.com/bmatsuo/lmdb-go这个开源工具。
具体使用代码请参考我的github
https://github.com/ClawHub/go-study.git
直接上代码:

结构体

//lmdb客户端结构体 只创建一个lmdb环境,一个DB库
type lmdbCliet struct {
 Env *lmdb.Env
 DBI lmdb.DBI
}

获取lmdb客户端

/**
 * 获取lmdb客户端
 *size: sets the size of the environment memory map.
 *path: Open an environment handle path
 *name: dbi name
 */
func NewClient(size int64, path string, name string) *lmdbCliet {
 //获取lmdb环境
 env, err := lmdb.NewEnv()
 if err != nil {
 log.LmdbLogger.Error("获取lmdb环境失败", zap.Error(err))
 }
 //设置最大库数量
 err = env.SetMaxDBs(1)
 if err != nil {
 log.LmdbLogger.Error("设置最大库数量失败", zap.Int("maxDBs", 1), zap.Error(err))
 }
 //设置最大存储
 err = env.SetMapSize(size)
 if err != nil {
 log.LmdbLogger.Error("设置最大存储失败", zap.Int64("mapSize", size), zap.Error(err))
 }
 //环境打开,Open an environment handle
 //modo:UNIX权限,用于设置创建的文件和信号量。
 err = env.Open(path, 0, 0644)
 if err != nil {
 log.LmdbLogger.Error("环境打开失败", zap.String("path", path), zap.Error(err))
 }
 //ReaderCheck从reader lock表中清除陈旧的条目,并返回清除的条目数量。
 readers, err := env.ReaderCheck()
 if err != nil {
 log.LmdbLogger.Error("ReaderCheck失败", zap.Int("readers", readers), zap.Error(err))
 } else {
 log.LmdbLogger.Info("ReaderCheck", zap.Int("readers", readers))
 }
 //创建DBI
 var dbi lmdb.DBI
 err = env.Update(func(txn *lmdb.Txn) (err error) {
 //dbi, err = txn.CreateDBI("example")
 dbi, err = txn.CreateDBI(name)
 fmt.Println(err)
 return
 })
 if err != nil {
 log.LmdbLogger.Error("创建DBI失败", zap.String("dbName", name), zap.Error(err))
 }
 return &lmdbCliet{env, dbi}
}

关闭环境

//close
func (c *lmdbCliet) Close() {
 if c.Env != nil {
 err := c.Env.Close()
 if err != nil {
 log.LmdbLogger.Error("Close fail", zap.Error(err))
 }
 }
}

获取db状态

//stat
func (c *lmdbCliet) Stat() string {
 stat, err := c.Env.Stat()
 if err != nil {
 if err != nil {
 log.LmdbLogger.Error("Stat fail", zap.Error(err))
 }
 return "stat error"
 }
 //json解析
 bytes, err := json.Marshal(stat)
 if err != nil {
 log.LmdbLogger.Error("Stat json Marshal fail", zap.Error(err))
 return "json marshal error"
 }
 return string(bytes)
}

简单方法封装

get
//get
func (c *lmdbCliet) Get(key string) string {
 //默认值""
 var result string
 _ = c.Env.View(func(txn *lmdb.Txn) (err error) {
 v, err := txn.Get(c.DBI, []byte(key))
 if err != nil {
 if err != nil {
 log.LmdbLogger.Error("Get fail", zap.String("key", key), zap.Error(err))
 }
 return err
 }
 //获取成功
 result = string(v)
 return nil
 })
 return result
}
set
//set
func (c *lmdbCliet) Set(key, val string) bool {
 //默认false
 var result bool
 _ = c.Env.Update(func(txn *lmdb.Txn) error {
 err := txn.Put(c.DBI, []byte(key), []byte(val), 0)
 if err != nil {
 if err != nil {
 log.LmdbLogger.Error("Set fail", zap.String("key", key), zap.String("val", val), zap.Error(err))
 }
 return err
 }
 //插入成功
 result = true
 return nil
 })
 return result
}

del

//Del
func (c *lmdbCliet) Del(key string) bool {
 //默认false
 var result bool
 _ = c.Env.Update(func(txn *lmdb.Txn) error {
 err := txn.Del(c.DBI, []byte(key), nil)
 if err != nil {
 if err != nil {
 log.LmdbLogger.Error("Del fail", zap.String("key", key), zap.Error(err))
 }
 return err
 }
 //删除成功
 result = true
 return nil
 })
 return result
}
batch put
//batch put
func (c *lmdbCliet) BatchPut(keyValMap map[string]string, commitNum int) bool {
 //使用锁,因为采用了mdb_txn_begin
 runtime.LockOSThread()
 defer runtime.UnlockOSThread()
 //默认false
 var result bool
 //开始事务
 txn, err := (c.Env).BeginTxn(nil, 0)
 if err != nil {
 log.LmdbLogger.Error("BeginTxn fail", zap.Error(err))
 return result
 }
 //打开游标
 var cur *lmdb.Cursor
 cur, err = txn.OpenCursor(c.DBI)
 if err != nil {
 log.LmdbLogger.Error("OpenCursor fail", zap.Error(err))
 return result
 }
 //入游标数量
 var num = 1
 //迭代待处理数据
 for key, val := range keyValMap {
 //入游标
 err = cur.Put([]byte(key), []byte(val), 0)
 if err != nil {
 log.LmdbLogger.Error("cur.Put fail", zap.String("key", key), zap.String("val", val), zap.Error(err))
 return result
 }
 //达到提交数量
 if num%commitNum == 0 {
 //提交事务
 err = txn.Commit()
 if err != nil {
 log.LmdbLogger.Error("txn.Commit() fail", zap.Error(err))
 return result
 }
 //新开启事务
 txn, err := (c.Env).BeginTxn(nil, 0)
 if err != nil {
 log.LmdbLogger.Error("BeginTxn fail", zap.Error(err))
 return result
 }
 //新开游标
 cur, err = txn.OpenCursor(c.DBI)
 if err != nil {
 log.LmdbLogger.Error("OpenCursor fail", zap.Error(err))
 return result
 }
 }
 //入游标数量+1
 num++
 }
 //最后提交一次事务
 //提交事务
 err = txn.Commit()
 if err != nil {
 log.LmdbLogger.Error("txn.Commit() fail", zap.Error(err))
 return result
 }
 return true
}

测试

func Demo() {
 log.LmdbLogger.Info("------lmdb---------")
 size := int64(102400)
 path := "F:\\lmdb"
 name := "db"
 client := NewClient(size, path, name)
 flag := client.Set("sex", "nan")
 log.LmdbLogger.Info("Set", zap.Bool("flag", flag))
 sex := client.Get("sex")
 log.LmdbLogger.Info(sex)
 log.LmdbLogger.Info(client.Stat())
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:clawhub

查看原文:Golang使用LMDB

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1585 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏