前面已經講過一些Go語言的基礎知識,感興趣的朋友可以先看看之前的文章。https://www.cnblogs.com/zhangweizhong/category/1275863.html。
今天就來講講go 里面的如何使用 Redis。
安裝
1. Redis 的安裝很簡單,我這里測試直接用的是windows 的版本。如何安裝就不細說了。想了解的可以看之前的文章:https://www.cnblogs.com/zhangweizhong/category/771056.html
2. golang 客戶端,用的是 go-redis,
1. go get github.com/go-redis
2. 接着在代碼中導入此包即可:
import "github.com/go-redis/redis"
基本操作
創建Redis連接客戶端
通過 redis.NewClient 函數即可創建一個 redis 客戶端, 這個方法接收一個 redis.Options 對象參數, 通過這個參數, 我們可以配置 redis 相關的屬性, 例如 redis 服務器地址, 數據庫名, 數據庫密碼等。
// 創建 redis 客戶端
func GetRedisClient() *Client { redisdb := NewClient(&Options{ Addr: "127.0.0.1:6379", Password: "", // no password set DB: 0, // use default DB }) pong, err := redisdb.Ping().Result() if err != nil { fmt.Println(pong, err) } return redisdb }
通過 cient.Ping() 來檢查是否成功連接到了 redis 服務器
String 操作
S
et(key, value):給數據庫中名稱為key的string賦予值valueget(key):返回數據庫中名稱為key的string的value
GetSet(key, value):給名稱為key的string賦予上一次的value
MGet(key1, key2,…, key N):返回庫中多個string的value
SetNX(key, value):添加string,名稱為key,值為value
SetXX(key, time, value):向庫中添加string,設定過期時間time
MSet(key N, value N):批量設置多個string的值
MSetNX(key N, value N):如果所有名稱為key i的string都不存在
Incr(key):名稱為key的string增1操作
Incrby(key, integer):名稱為key的string增加integer
Decr(key):名稱為key的string減1操作
Decrby(key, integer):名稱為key的string減少integer
Append(key, value):名稱為key的string的值附加valuesubstr(key, start, end):返回名稱為key的string的value的子串
func StringDemo() { fmt.Println("-----------------------welcome to StringDemo-----------------------") redisClient:=GetRedisClient() if redisClient ==nil{ fmt.Errorf("StringDemo redisClient is nil") return } name := "張三" key :="name:zhangsan" redisClient.Set(key , name,1 * time.Second) val := redisClient.Get(key) if val == nil { fmt.Errorf("StringDemo get error") } fmt.Println("name", val) }
List 操作
RPush(key, value):在名稱為key的list尾添加一個值為value的元素
LPush(key, value):在名稱為key的list頭添加一個值為value的 元素
LLen(key):返回名稱為key的list的長度
LRange(key, start, end):返回名稱為key的list中start至end之間的元素
LTrim(key, start, end):截取名稱為key的list
LIndex(key, index):返回名稱為key的list中index位置的元素
LSet(key, index, value):給名稱為key的list中index位置的元素賦值
LRem(key, count, value):刪除count個key的list中值為value的元素
LPop(key):返回並刪除名稱為key的list中的首元素
RPop(key):返回並刪除名稱為key的list中的尾元素
BLPop(key1, key2,… key N, timeout):lpop命令的block版本。
BRPop(key1, key2,… key N, timeout):rpop的block版本。
RPopLPush(srckey, dstkey):返回並刪除名稱為srckey的list的尾元素,並將該元素添加到名稱為dstkey的list的頭部
func ListDemo(){ fmt.Println("-----------------------welcome to ListDemo-----------------------") redisClient:=GetRedisClient() if redisClient == nil { fmt.Errorf("ListDemo redisClient is nil") return } articleKey := "article" result,err:=redisClient.RPush(articleKey, "a","b","c").Result() // if err!=nil { fmt.Println(err) return } fmt.Println("result:",result) result,err = redisClient.LPush(articleKey, "d").Result() // if err!=nil { fmt.Println(err) return } fmt.Println("result:",result) length, err := redisClient.LLen(articleKey).Result() if err != nil { fmt.Println("ListDemo LLen is nil") } fmt.Println("length: ", length) // 長度 mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() if err1!=nil { fmt.Println(err1) return } for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } }
Hash 操作
HSet(key, field, value):向名稱為key的hash中添加元素field
HGet(key, field):返回名稱為key的hash中field對應的value
HMget(key, (fields)):返回名稱為key的hash中field i對應的value
HMset(key, (fields)):向名稱為key的hash中添加元素field
HIncrby(key, field, integer):將名稱為key的hash中field的value增加integer
HExists(key, field):名稱為key的hash中是否存在鍵為field的域
HDel(key, field):刪除名稱為key的hash中鍵為field的域
HLen(key):返回名稱為key的hash中元素個數
HKeys(key):返回名稱為key的hash中所有鍵
HVals(key):返回名稱為key的hash中所有鍵對應的value
HGetall(key):返回名稱為key的hash中所有的鍵(field)及其對應的value
func HashDemo() { fmt.Println("-----------------------welcome to HashDemo-----------------------") redisClient := GetRedisClient() if redisClient == nil { fmt.Errorf("HashDemo redisClient is nil") return } article := Article{18, "測試文章內容22222", "測試文章內容22222測試文章內容22222測試文章內容22222", 10, 0} articleKey := "article:18" redisClient.HMSet(articleKey, ToStringDictionary(&article)) mapOut := redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") redisClient.HSet(articleKey, "Content", "測試文章內容") mapOut = redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() if err != nil { fmt.Printf("\n HIncrBy error=%s ", err) } else { fmt.Printf("\n HIncrBy Views=%d ", view) } fmt.Print("\n") mapOut = redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") }
連接池
go-redis 已經實現了 redis 的連接池管理, 因此我們不需要自己手動管理 redis 的連接。
默認情況下,連接池大小是10, 可以通過 redis.Options 的 PoolSize 屬性, 我們設置了 redis 連接池的大小為5。
func GetRedisClientPool() *Client{ redisdb := NewClient(&Options{ Addr: "127.0.0.1:6379", Password: "", DB: 0, PoolSize: 5,}) pong, err := redisdb.Ping().Result() if err != nil { fmt.Println(pong, err) } return redisdb }
// 連接池測試 func connectPoolTest() { fmt.Println("-----------------------welcome to connect Pool Test-----------------------") client :=GetRedisClientPool() wg := sync.WaitGroup{} wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() for j := 0; j < 1000; j++ { client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() client.Get(fmt.Sprintf("name%d", j)).Result() } fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d\n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); }() } wg.Wait() }
完整代碼
package main import ( "fmt" . "github.com/go-redis/redis" . "redisDemo/models" "time" "sync" ) func main() { fmt.Println("-----------------------welcome to redisdemo-----------------------") //StringDemo() //ListDemo() //HashDemo() connectPoolTest() } func StringDemo() { fmt.Println("-----------------------welcome to StringDemo-----------------------") redisClient:=GetRedisClient() if redisClient ==nil{ fmt.Errorf("StringDemo redisClient is nil") return } name := "張三" key :="name:zhangsan" redisClient.Set(key , name,1 * time.Second) val := redisClient.Get(key) if val == nil { fmt.Errorf("StringDemo get error") } fmt.Println("name", val) } func ListDemo(){ fmt.Println("-----------------------welcome to ListDemo-----------------------") redisClient:=GetRedisClient() if redisClient == nil { fmt.Errorf("ListDemo redisClient is nil") return } articleKey := "article" result,err:=redisClient.RPush(articleKey, "a","b","c").Result() //在名稱為 key 的list尾添加一個值為value的元素 if err!=nil { fmt.Println(err) return } fmt.Println("result:",result) result,err = redisClient.LPush(articleKey, "d").Result() //在名稱為 key 的list頭添加一個值為value的元素 if err!=nil { fmt.Println(err) return } fmt.Println("result:",result) length, err := redisClient.LLen(articleKey).Result() if err != nil { fmt.Println("ListDemo LLen is nil") } fmt.Println("length: ", length) // 長度 mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() if err1!=nil { fmt.Println(err1) return } for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } } func HashDemo() { fmt.Println("-----------------------welcome to HashDemo-----------------------") redisClient := GetRedisClient() if redisClient == nil { fmt.Errorf("HashDemo redisClient is nil") return } article := Article{18, "測試文章內容22222", "測試文章內容22222測試文章內容22222測試文章內容22222", 10, 0} articleKey := "article:18" redisClient.HMSet(articleKey, ToStringDictionary(&article)) mapOut := redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") redisClient.HSet(articleKey, "Content", "測試文章內容") mapOut = redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() if err != nil { fmt.Printf("\n HIncrBy error=%s ", err) } else { fmt.Printf("\n HIncrBy Views=%d ", view) } fmt.Print("\n") mapOut = redisClient.HGetAll(articleKey).Val() for inx, item := range mapOut { fmt.Printf("\n %s:%s", inx, item) } fmt.Print("\n") } func GetRedisClient() *Client { redisdb := NewClient(&Options{ Addr: "127.0.0.1:6379", Password: "", // no password set DB: 0, // use default DB }) pong, err := redisdb.Ping().Result() if err != nil { fmt.Println(pong, err) } return redisdb } func GetRedisClientPool() *Client{ redisdb := NewClient(&Options{ Addr: "127.0.0.1:6379", Password: "", DB: 0, PoolSize: 5,}) pong, err := redisdb.Ping().Result() if err != nil { fmt.Println(pong, err) } return redisdb } // 連接池測試 func connectPoolTest() { fmt.Println("-----------------------welcome to connect Pool Test-----------------------") client :=GetRedisClientPool() wg := sync.WaitGroup{} wg.Add(10) for i := 0; i < 10; i++ { go func() { defer wg.Done() for j := 0; j < 1000; j++ { client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() client.Get(fmt.Sprintf("name%d", j)).Result() } fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d\n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); }() } wg.Wait() }
最后
1. go語言使用Redis 還是非常簡單的,以上已經把Redis 的基本的用法講完了。大家可以自己動手寫代碼試試。
2. 完整代碼:點擊下載