golang 操做redis5大數據類型(string、hash、list、set、zset)(go-redis)

前言

使用redis首先要部署redis,載個安裝包,部署下便可,本文不贅述了。redis官網:https://redis.io/git

接着要下載golang的redis資源包,golang官方推薦的有redisgo和go-reids,我的認爲go-redis的封裝更加人性化,redisgo的調用是基於命令的,go-redis是基於方法的,因此本文先來介紹go-redis的使用。github

2行代碼來比較下2種資源包的調用方式:
redisgo: client.Do("SET", "mykey", "我是數據", "EX", "3600")
go-redis:client.Set("mykey", "我是數據", time.Hour)
一樣是存儲一個1小時後過時的數據,go-redis的調用方式明顯更友好。golang

導入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目錄下)。redis

image.png

下載完成會在GOPATH下的src裏多了資源包json

image.png

導入包:測試

import (  
    "github.com/go-redis/redis" 
)

一、連接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()spa

二、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)

存儲命令:Set,過時時間若是是3分鐘則寫成 3*timt.Minute
client.Set(key, "我是值", time.Hour)
讀取命令:Get
value, err := client.Get(key).Result()命令行

三、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)code

四、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*6060秒內有數據加入,被取出爲止。
first2, _ := client.BLPop(time.Second*60, listKey).Result()
獲取整個列表數據,這是不會移除數據的
listGet, _ := client.LRange(listKey, 1, 2).Result()
關於list的命令還有不少,例如LPush、Rpop、BRpop、LLen等等

五、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()

六、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()

六、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類型,裏面包含ScoreMember2個屬性
client.ZAdd(zsetKey, ranking...)
給鍾南山加上5分,返回鍾南山的最新熱度分值
newScore, err := client.ZIncrBy(zsetKey, 5.0, "鍾南山").Result()
獲取前2名熱度的醫生,前2名,因此索引是從0到1。
zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result()

七、設置過時時間

操做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命令,使用起來也是很順暢的。

相關文章
相關標籤/搜索