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 相关文章推荐
golang如何去除多余空白字符(含制表符)
Apr 25 Golang
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
解决golang在import自己的包报错的问题
Apr 29 Golang
golang slice元素去重操作
Apr 30 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
Golang 编译成DLL文件的操作
May 06 Golang
关于golang高并发的实现与注意事项说明
May 08 Golang
浅谈Golang 切片(slice)扩容机制的原理
Jun 09 Golang
Go语言基础map用法及示例详解
Nov 17 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Go获取两个时区的时间差
Apr 20 Golang
深入理解 Golang 的字符串
May 04 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的历史和优缺点
2006/10/09 PHP
让你的WINDOWS同时支持MYSQL4,MYSQL4.1,MYSQL5X
2006/12/06 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
2015/08/08 PHP
PHP和MySql中32位和64位的整形范围是多少
2016/02/18 PHP
thinkphp5+layui实现的分页样式示例
2019/10/08 PHP
php远程请求CURL实例教程(爬虫、保存登录状态)
2020/12/10 PHP
通用JS事件写法实现代码
2009/01/07 Javascript
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
js delete 用法(删除对象属性及变量)
2014/08/24 Javascript
超炫的jquery仿flash导航栏特效
2014/11/11 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
Jquery 自定义事件实现发布/订阅的简单实例
2016/06/12 Javascript
关于webuploader插件使用过程遇到的小问题
2016/11/07 Javascript
12个非常有用的JavaScript技巧
2017/05/17 Javascript
vue2.5.2使用http请求获取静态json数据的实例代码
2018/02/27 Javascript
Vue中Table组件Select的勾选和取消勾选事件详解
2019/03/19 Javascript
微信小程序分享小程序码的生成(带参数)以及参数的获取
2020/03/25 Javascript
用python找出那些被“标记”的照片
2017/04/20 Python
Tensorflow使用tfrecord输入数据格式
2018/06/19 Python
简单了解python单例模式的几种写法
2019/07/01 Python
opencv python 图像轮廓/检测轮廓/绘制轮廓的方法
2019/07/03 Python
Python3内置模块random随机方法小结
2019/07/13 Python
Django Form 实时从数据库中获取数据的操作方法
2019/07/25 Python
python实现的批量分析xml标签中各个类别个数功能示例
2019/12/30 Python
Tensorflow实现在训练好的模型上进行测试
2020/01/20 Python
jupyter notebook 增加kernel教程
2020/04/10 Python
python 两种方法删除空文件夹
2020/09/29 Python
python中@contextmanager实例用法
2021/02/07 Python
css3打造一款漂亮的卡哇伊按钮
2013/03/20 HTML / CSS
CSS3中新增的对文本和字体的设置
2020/02/03 HTML / CSS
突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述
2013/01/31 HTML / CSS
金融专业个人求职信范文
2013/11/28 职场文书
产品销售计划书
2014/05/04 职场文书
给老婆道歉的话
2015/01/20 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
MySQL之高可用集群部署及故障切换实现
2021/04/22 MySQL