golang 操作redis5大数据类型(string、hash、list、set、zset)(go-redis)
source link: https://studygolang.com/articles/26489
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
前言
使用redis首先要部署redis,载个安装包,部署下即可,本文不赘述了。redis官网: https://redis.io/
接着要下载golang的redis资源包,golang官方推荐的有redisgo和go-reids,个人认为go-redis的封装更加人性化,redisgo的调用是基于命令的,go-redis是基于方法的,所以本文先来介绍go-redis的使用。
2行代码来比较下2种资源包的调用方式:
redisgo:client.Do("SET", "mykey", "我是数据", "EX", "3600")
go-redis:
client.Set("mykey", "我是数据", time.Hour)
同样是存储一个1小时后过期的数据,go-redis的调用方式明显更友好。
导入go-redis包
github地址: https://github.com/go-redis/redis
文档地址: https://godoc.org/github.com/go-redis/redis
golang下载资源包相当方便,打开命令行,输入命令: go get -u github.com/go-redis/redis
(使用git命令下载资源包,需要先安装git,没安装git的同学可以手动下载后放入src目录下)。
下载完成会在GOPATH下的src里多了资源包
导入包:
import ( "github.com/go-redis/redis" )
1、链接redis
client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "123456", DB: 0, }) //延迟到程序结束关闭链接 defer client.Close() //ping pong, err := client.Ping().Result() if err != nil { fmt.Println("ping error", err.Error()) return } fmt.Println("ping result:", pong)
解析:
Addr
是redis服务的地址,如果部署的reids没有密码,那 Password
就写 ""
, DB
是对应reids 0-15的db
测试redis链接:
pong, err := client.Ping().Result()
2、string 字符串
//string------------------------------------------------------------------------ key := "go2key" //过期时间1小时 err = client.Set(key, "我是值", time.Hour).Err() if err != nil { fmt.Println("set err", err) return } //获取 value, err := client.Get(key).Result() if err != nil { fmt.Println("Get err", err) return } fmt.Printf("key:%v 值:%~~~~v \n", key, value)
3*timt.Minute
client.Set(key, "我是值", time.Hour)
读取命令:Get
value, err := client.Get(key).Result()
3、struc 结构
//json--------------------------------- //存储结构 doctor := Doctor{1, "钟南山", 83, 1, time.Now()} doctorJson, _ := json.Marshal(doctor) client.Set("doctor2", doctorJson, time.Hour) //读取结构 doctorResult, _ := client.Get("doctor2").Result() var doctor2 Doctor //反序列化 json.Unmarshal([]byte(doctorResult), &doctor2) fmt.Println("doctor2", doctor2)
解析:
存储结构其实也是存储string,只是把struc序列化成json,等读取的时候再反序列化成struc
序列化:
doctorJson, _ := json.Marshal(doctor)
反序列化:
json.Unmarshal([]byte(doctorResult), &doctor2)
4、list 列表
list是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
//list---------------------------------------------------- //通道列表 list listKey := "go2list" client.RPush(listKey, "str1", 10, "str2", 15, "str3", 20).Err() //lpop 取出并移除左边第一个元素 first, _ := client.LPop(listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first[0], first[1]) //Blpop 取出并移除左边第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 first2, _ := client.BLPop(time.Second*60, listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first2[0], first2[1]) //数据长度 listLen, _ := client.LLen(listKey).Result() fmt.Println("list length", listLen) //获取列表 listGet, _ := client.LRange(listKey, 1, 2).Result() fmt.Println("索引1-2的2个元素元素", listGet)
解析:
存储 "str1", 10, "str2", 15, "str3", 20
这6个元素到 "go2list"
中,使用RPush命令往队列右边加入。
从左边取出第一个元素,取出后,这个元素将会从list里移除,这就很像我们的消息队列了。
first, _ := client.LPop(listKey).Result()
BLPop获取左边第一个元素,如果不存在元素,则会一直堵塞,直到 time.Second*60
60秒内有数据加入,被取出为止。
first2, _ := client.BLPop(time.Second*60, listKey).Result()
获取整个列表数据,这是不会移除数据的
listGet, _ := client.LRange(listKey, 1, 2).Result()
关于list的命令还有很多,例如LPush、Rpop、BRpop、LLen等等
5、hash
hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。可以不用直接获取和更新对象的某个属性。
//hash------------------------------------------- hashKey := "userkey_1" //set hash 适合存储结构 client.HSet(hashKey, "name", "叶子") client.HSet(hashKey, "age", 18) //get hash hashGet, _ := client.HGet(hashKey, "name").Result() fmt.Println("HGet name", hashGet) //获取所有hash 返回map hashGetAll, _ := client.HGetAll(hashKey).Result() fmt.Println("HGetAll", hashGetAll)
解析:
存储name属性为叶子,age属性为18的对象到userkey_1中
client.HSet(hashKey, "name", "叶子")
获取某个属性
hashGet, _ := client.HGet(hashKey, "name").Result()
获取userkey_1所有的属性,返回的是一个map对象
hashGetAll, _ := client.HGetAll(hashKey).Result()
6、set 集合
set 是 string 类型的无序集合。
//set-------------------------------------------- setKey := "go2set" client.SAdd(setKey, "set1") client.SAdd(setKey, "set2") client.SAdd(setKey, "set3") client.SAdd(setKey, "set4") //获取集合的所有成员 setList, _ := client.SMembers(setKey).Result() fmt.Println("GetSet", setList) //移除集合里的set1 client.SRem(setKey, "set1") //移除并返回set的一个随机元素 setFirst, _ := client.SPop(setKey).Result() fmt.Println("setFirst", setFirst)
解析:
往集合里添加数据
client.SAdd(setKey, "set1")
获取集合的所有的元素
setList, _ := client.SMembers(setKey).Result()
移除并返回set的一个随机元素,因为set是无序的
setFirst, _ := client.SPop(setKey).Result()
6、zset 有序集合
set是有序的,适合做排行榜业务,我们来模拟一个医生热度排行
//zset------------------------------------------------ zsetKey := "go2zset" ranking := []*redis.Z{ &redis.Z{Score: 100.0, Member: "钟南山"}, &redis.Z{Score: 80.0, Member: "林医生"}, &redis.Z{Score: 70.0, Member: "王医生"}, &redis.Z{Score: 75.0, Member: "张医生"}, &redis.Z{Score: 59.0, Member: "叶医生"}, } client.ZAdd(zsetKey, ranking...) //golang+5分 newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result() fmt.Println("钟南山加5分后的最新分数", newScore) //取zset里的前2名热度的医生 zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result() fmt.Println("zset前2名热度的医生", zsetList2)
解析:
往zset里加入集合数据,数据是 []*redis.Z
类型,里面包含 Score
和 Member
2个属性
client.ZAdd(zsetKey, ranking...)
给钟南山加上5分,返回钟南山的最新热度分值
newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result()
获取前2名热度的医生,前2名,所以索引是从0到1。
zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result()
7、设置过期时间
操作string数据的时候,可以在方法里直接传入过期时间。但list、hash、set、zset都没有直接提供相应参数,但redis可以额外设置key的过期时间
//Expire------------------------------------------ //设置过期时间 30秒后过期 client.Expire(hashKey, time.Second*30) client.ExpireAt(hashKey, time.Now().Add(time.Second*30)) //删除key //client.Del("go2key", "go2list") //ttl 获取key的生存时间 duration, err := client.TTL(key).Result() if err != nil { fmt.Println("TTL err", err) return } fmt.Printf("key%v的有效时间,%v,%v \n", key, duration.String(), duration.Seconds())
完整demo
package main import ( "encoding/json" "fmt" "github.com/go-redis/redis" "time" ) type Doctor struct { ID int64 Name string Age int Sex int AddTime time.Time } func main() { client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "123456", DB: 0, }) //延迟到程序结束关闭链接 defer client.Close() //ping pong, err := client.Ping().Result() if err != nil { fmt.Println("ping error", err.Error()) return } fmt.Println("ping result:", pong) //string------------------------------------------------------------------------ key := "go2key" //过期时间1小时 err = client.Set(key, "我是值", time.Hour).Err() if err != nil { fmt.Println("set err", err) return } //获取 value, err := client.Get(key).Result() if err != nil { fmt.Println("Get err", err) return } fmt.Printf("key:%v 值:%v \n", key, value) //list------------------------------------------------------------------------ //通道列表 list listKey := "go2list" client.RPush(listKey, "str1", 10, "str2", 15, "str3", 20).Err() //lpop 取出并移除左边第一个元素 first, _ := client.LPop(listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first[0], first[1]) //Blpop 取出并移除左边第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 first2, _ := client.BLPop(time.Second*60, listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first2[0], first2[1]) //数据长度 listLen, _ := client.LLen(listKey).Result() fmt.Println("list length", listLen) //获取列表 listGet, _ := client.LRange(listKey, 1, 2).Result() fmt.Println("索引1-2的2个元素元素", listGet) //json------------------------------------------------------------------------ //存储结构 doctor := Doctor{1, "钟南山", 83, 1, time.Now()} doctorJson, _ := json.Marshal(doctor) client.Set("doctor2", doctorJson, time.Hour) //读取结构 doctorResult, _ := client.Get("doctor2").Result() var doctor2 Doctor //反序列化 json.Unmarshal([]byte(doctorResult), &doctor2) fmt.Println("doctor2", doctor2) //hash------------------------------------------------------------------------ hashKey := "gohash" //set hash 适合存储结构 client.HSet(hashKey, "name", "叶子") client.HSet(hashKey, "age", 18) //get hash hashGet, _ := client.HGet(hashKey, "name").Result() fmt.Println("HGet name", hashGet) //获取所有hash 返回map hashGetAll, _ := client.HGetAll(hashKey).Result() fmt.Println("HGetAll", hashGetAll) //set------------------------------------------------------------------------ setKey := "go2set" client.SAdd(setKey, "set1") client.SAdd(setKey, "set2") client.SAdd(setKey, "set3") client.SAdd(setKey, "set4") //获取集合的所有成员 setList, _ := client.SMembers(setKey).Result() fmt.Println("GetSet", setList) //移除集合里的set1 client.SRem(setKey, "set1") //移除并返回set的一个随机元素 setFirst, _ := client.SPop(setKey).Result() fmt.Println("set的随机元素", setFirst) //zset------------------------------------------------------------------------ zsetKey := "go2zset" ranking := []*redis.Z{ &redis.Z{Score: 100.0, Member: "钟南山"}, &redis.Z{Score: 80.0, Member: "林医生"}, &redis.Z{Score: 70.0, Member: "王医生"}, &redis.Z{Score: 75.0, Member: "张医生"}, &redis.Z{Score: 59.0, Member: "叶医生"}, } client.ZAdd(zsetKey, ranking...) //golang+5分 newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result() fmt.Println("钟南山加5分后的最新分数", newScore) //取zset里的前2名热度的医生 zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result() fmt.Println("zset前2名热度的医生", zsetList2) //Expire------------------------------------------------------------------------ //设置过期时间 30秒后过期 client.Expire(hashKey, time.Second*30) client.ExpireAt(hashKey, time.Now().Add(time.Second*30)) //删除key //client.Del("go2key", "go2list") //ttl 获取key的生存时间 duration, err := client.TTL(key).Result() if err != nil { fmt.Println("TTL err", err) return } fmt.Printf("key%v的有效时间,%v,%v \n", key, duration.String(), duration.Seconds()) }
总结
以上就是redis常用的方法示例,go-redis的封装非常的友好,所有的方法名与redis自己的命令都是相对应的,非常易于理解,即便不看文档,只要你熟悉redis命令,使用起来也是很顺畅的。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK