GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结


Posted in Golang onJune 14, 2022

上一篇文章为大家介绍了 GoFrame gcache使用实践 | 缓存控制 淘汰策略 ,得到了大家积极的反馈。

后续几篇文章再接再厉,仍然为大家介绍GoFrame框架缓存相关的知识点,以及自己项目使用中的一些总结思考,GoFrame框架下文简称gf。

这篇文章比较硬核,爆肝2千字,阅读大约需要5~8分钟。

详细的介绍了gredis的使用,包括:Do/DoVar方法的使用及区别、复杂场景下使用Conn方法从连接池中获取一个redis连接对象、当给定的参数为mapslicestruct时,gredis内部支持自动对其使用json序列化,并且读取数据时可使用gvar.Var的转换功能实现反序列化。

GoFrame gredis

整体介绍

Redis客户端由gredis模块实现,底层采用了链接池设计。

gredis使用了连接池来进行Redis连接管理,通过Config配置对象或者Set*方法可以对连接池的属性进行管理,通过Stats方法可以获取连接池的统计信息。

我们最常用的是Do/DoVar方法,执行同步指令,通过向Redis Server发送对应的Redis API命令,来使用Redis Server的服务。Do/Var方法最大的特点是内部自行从连接池中获取连接对象,使用完毕后自动丢回连接池中,开发者无需手动调用Close方法,方便使用。

Do/DoVar方法

我们最常用的是Do/DoVar方法,执行同步指令,通过向Redis Server发送对应的Redis API命令,来使用Redis Server的服务。

Do/Var方法最大的特点是内部自行从连接池中获取连接对象,使用完毕后自动丢回连接池中,开发者无需手动调用Close方法,方便使用。

小技巧

DoDoVar的区别在于返回的结果类型不一样,DoVar返回的是gvar.Var类型,该类型对象可以执行非常方便的类型转换。

gvar.Var类型 就像go原生提供的interface一样

基本使用

package main

import (
	"fmt"
	"github.com/gogf/gf/frame/g"
)

func main() {
	g.Redis().Do("SET", "k", "v")
	v, _ := g.Redis().DoVar("GET", "k")
	fmt.Println(v.String())
}
复制代码

HSET/HGETALL操作

Hset 命令用于为哈希表中的字段赋值 。

如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。

如果字段已经存在于哈希表中,旧值将被覆盖。

package main

import (
	"fmt"
	"github.com/gogf/gf/container/gvar"
	"github.com/gogf/gf/frame/g"
)

func main() {
	var (
		err    error
		result *gvar.Var
		key    = "user"
	)
	_, err = g.Redis().Do("HSET", key, "id", 10000)
	if err != nil {
		panic(err)
	}
	_, err = g.Redis().Do("HSET", key, "name", "王中阳")
	if err != nil {
		panic(err)
	}
	result, err = g.Redis().DoVar("HGETALL", key)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.Map()) //打印结果: map[id:10000 name:王中阳]
}
复制代码

HMSET/HMGET操作

强烈推荐,非常好用:我们可以通过map参数执行HMSET操作。

package main

import (
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gutil"
)

func main() {
	var (
		key  = "user_100"
		data = g.Map{
			"name":  "王中阳",
			"sex":   0,
			"score": 100,
		}
	)
	_, err := g.Redis().Do("HMSET", append(g.Slice{key}, gutil.MapToSlice(data)...)...)
	if err != nil {
		g.Log().Fatal(err)
	}
	v, err := g.Redis().DoVar("HMGET", key, "name")
	if err != nil {
		g.Log().Fatal(err)
	}
	fmt.Println(v.Slice())  //打印结果 [王中阳]
}
复制代码

我们也可以通过struct参数执行HMSET操作。

package main

import (
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gutil"
)

func main() {
	type User struct {
		Name  string `json:"name"`
		Sex   int    `json:"sex"`
		Score int    `json:"score"`
	}
	var (
		key  = "user_100"
		data = &User{
			Name:  "王中阳",
			Sex:   0,
			Score: 100,
		}
	)
	_, err := g.Redis().Do("HMSET", append(g.Slice{key}, gutil.StructToSlice(data)...)...)
	if err != nil {
		g.Log().Fatal(err)
	}
	v, err := g.Redis().DoVar("HMGET", key, "name")
	if err != nil {
		g.Log().Fatal(err)
	}
	fmt.Println(v.Slice()) //打印结果: [王中阳]
}
复制代码

Conn连接对象

使用Do/DoVar方法已经能够满足绝大部分的场景需要,如果需要更复杂的Redis操作,我们可以使用Conn方法从连接池中获取一个连接对象,随后使用该连接对象进行操作。

需要注意的是,该连接对象不再使用时,应当显式调用Close方法进行关闭(丢回连接池)。

由于该Conn是个连接对象,注意该对象存在连接超时的限制,超时和服务端配置有关。

基本使用

package main

import (
    "fmt"
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/util/gconv"
)

func main() {
    conn := g.Redis().Conn()
    defer conn.Close()
    conn.Do("SET", "k", "v")
    v, _ := conn.Do("GET", "k")
    fmt.Println(gconv.String(v)) //打印结果:v
}
复制代码

Send批量指令

Send可以执行批量指令,并通过Receive方法一一获取返回结果。

package main

import (
    "fmt"
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/util/gconv"
)

func main() {
    conn := g.Redis().Conn()
    defer conn.Close()
    conn.Send("SET", "foo", "bar")
    conn.Send("GET", "foo")
    conn.Flush()
    // reply from SET
    conn.Receive()
    // reply from GET
    v, _ := conn.Receive()
    fmt.Println(gconv.String(v))  //打印结果:bar
}
复制代码

订阅/发布

我们可以通过RedisSUBSCRIBE/PUBLISH命令实现订阅/发布模式。

package main

import (
    "fmt"
    "github.com/gogf/gf/frame/g"
    "github.com/gogf/gf/util/gconv"
)

func main() {
    conn := g.Redis().Conn()
    defer conn.Close()
    _, err := conn.Do("SUBSCRIBE", "channel")
    if err != nil {
        panic(err)
    }
    for {
        reply, err := conn.Receive()
        if err != nil {
            panic(err)
        }
        fmt.Println(gconv.Strings(reply))
    }
}
复制代码

执行后,程序将阻塞等待获取数据。

另外打开一个终端通过redis-cli命令进入Redis Server,发布一条消息:

$ redis-cli
127.0.0.1:6379> publish channel test
(integer) 1
127.0.0.1:6379>
复制代码

随后程序终端立即打印出从Redis Server获取的数据:

[message channel test]
复制代码

自动序列化/反序列化

当给定的参数为mapslicestruct时,gredis内部支持自动对其使用json序列化,并且读取数据时可使用gvar.Var的转换功能实现反序列化。

map存取

package test

import (
   "fmt"
   "github.com/gogf/gf/container/gvar"
   "github.com/gogf/gf/frame/g"
)

func Run1() {
   var (
      err    error
      result *gvar.Var
      key    = "test_user"
      data   = g.Map{
         "id":   7,
         "name": "王中阳",
      }
   )
   _, err = g.Redis().Do("SET", key, data)
   if err != nil {
      panic(err)
   }
   result, err = g.Redis().DoVar("GET", key)
   if err != nil {
      panic(err)
   }
   fmt.Println("result:", result) //result: {"id":7,"name":"王中阳"}
   fmt.Println("result.Map():", result.Map()) //result.Map(): map[id:7 name:王中阳]
}
复制代码

打印结果

GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结

struct存取

package test

import (
   "fmt"
   "github.com/gogf/gf/container/gvar"
   "github.com/gogf/gf/frame/g"
)

func Run1() {
   type User struct {
      Id   int
      Name string
   }
   var (
      err    error
      result *gvar.Var
      key    = "test_user"
      user   = &User{
         Id:   007,
         Name: "王中阳",
      }
   )

   _, err = g.Redis().Do("SET", key, user)
   if err != nil {
      panic(err)
   }
   result, err = g.Redis().DoVar("GET", key)
   if err != nil {
      panic(err)
   }

   var user2 *User
   if err = result.Struct(&user2); err != nil {
      panic(err)
   }
   fmt.Println("user2:", user2) //user2: &{7 王中阳}
   fmt.Printf("id:%v, name:%v \n", user2.Id, user2.Name) //id:7, name:王中阳
}
复制代码

打印结果

GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结

总结

这篇文章比较硬核,爆肝2千字。

详细的介绍了gredis的使用,包括:Do/DoVar方法的使用及区别、复杂场景下使用Conn方法从连接池中获取一个redis连接对象、当给定的参数为mapslicestruct时,gredis内部支持自动对其使用json序列化,并且读取数据时可使用gvar.Var的转换功能实现反序列化。

以上就是GoFrame gredis缓存DoVar Conn连接对象 自动序列化的详细内容,更多关于GoFrame gredis DoVar Conn连接对象 自动序列化的资料请关注三水点靠木其它相关文章!


Tags in this post...

Golang 相关文章推荐
Go语言操作数据库及其常规操作的示例代码
Apr 21 Golang
对Golang中的FORM相关字段理解
May 02 Golang
golang 实现Location跳转方式
May 02 Golang
golang elasticsearch Client的使用详解
May 05 Golang
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 Golang
再次探讨go实现无限 buffer 的 channel方法
Jun 13 Golang
Golang表示枚举类型的详细讲解
Sep 04 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang连接MySQl使用sqlx库
Apr 14 Golang
golang用type-switch判断interface的实际存储类型
Apr 14 Golang
Golang解析JSON对象
Apr 30 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Go调用Rust方法及外部函数接口前置
详解Go语言中配置文件使用与日志配置
Jun 01 #Golang
详解Go语言中Get/Post请求测试
Golang实现可重入锁的示例代码
May 25 #Golang
Go web入门Go pongo2模板引擎
May 20 #Golang
Go语言入门exec的基本使用
May 20 #Golang
Golang并发工具Singleflight
May 06 #Golang
You might like
PHP中10个不常见却非常有用的函数
2010/03/21 PHP
如何使用纯PHP实现定时器任务(Timer)
2015/07/31 PHP
laravel 操作数据库常用函数的返回值方法
2019/10/11 PHP
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
用js代码改变单选框选中状态的简单实例
2013/12/18 Javascript
学习使用grunt来打包JavaScript和CSS程序的教程
2016/01/04 Javascript
jquery按回车键实现表单提交的简单实例
2016/05/25 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
js仿QQ邮箱收件人选择与搜索功能
2017/02/10 Javascript
js编写选项卡效果
2017/05/23 Javascript
nodejs读取并去重excel文件
2018/04/22 NodeJs
VUE基于NUXT的SSR 服务端渲染
2018/11/30 Javascript
JavaScript制作3D旋转相册
2020/08/02 Javascript
python单元测试unittest实例详解
2015/05/11 Python
详解Python中find()方法的使用
2015/05/18 Python
python strip() 函数和 split() 函数的详解及实例
2017/02/03 Python
Python 关于反射和类的特殊成员方法
2017/09/14 Python
Django框架多表查询实例分析
2018/07/04 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
Python实现查找最小的k个数示例【两种解法】
2019/01/08 Python
Python实现字典按key或者value进行排序操作示例【sorted】
2019/05/03 Python
详解Python文件修改的两种方式
2019/08/22 Python
Python+PyQt5+MySQL实现天气管理系统
2020/06/16 Python
详解Python多线程下的list
2020/07/03 Python
Python如何发送与接收大型数组
2020/08/07 Python
python SOCKET编程基础入门
2021/02/27 Python
AmazeUI图片轮播效果的示例代码
2020/08/20 HTML / CSS
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
师范应届生求职信
2013/11/15 职场文书
百货商场楼层班组长竞聘书
2014/03/31 职场文书
在宿舍喝酒的检讨书
2014/09/28 职场文书
旷课检讨书500字
2014/10/14 职场文书
PyTorch中permute的使用方法
2022/04/26 Python
Redis keys命令的具体使用
2022/06/05 Redis
使用opencv-python如何打开USB或者笔记本前置摄像头
2022/06/21 Python
一文搞懂Java中的注解和反射
2022/06/21 Java/Android