golang操作redis-redigo库的使用
1. redis简单介绍
redis支持数据的持久化,将内存中的数据保存到磁盘中,重启的时候可以再次加载进行使用 redis不仅仅支持key-value数据,还支持:string,list,set,hash等 redis支持数据备份,即master-slaver模式的数据备份 读11w/s,写8W/s,单机能达到15W qps,性能极高,非常适合做缓存 redis的所有操作都是原子性的,单个操作是原子性的,多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来 redis与其它key-value的不同? 1. 有着更为复杂的数据结构并提供对它们的原子性操作 2. redis的数据类型都是基于基础的数据结构的同时对程序员透明,无须进行额外的抽象 redis运行在内存中但是可以持久化到磁盘,所在在对不同数据集进行告诉读写时需要权衡内存, 因为数据量不能大于硬件内存,内存数据库的另一个优点是:相比在磁盘上相同复杂的数据结构, 在内存中操作起来非常简单,这样redis可以做很多内部复杂性很强的事情, 同时,在磁盘方面,它们是以紧凑的追加的方式产生的,因为它们并不需要随机访问
2. 连接redis,新建包封装redis客户端结构体
package redisC
import (
"fmt"
"github.com/gomodule/redigo/redis"
)
type redisC struct {
Conn redis.Conn
}
func InitRedis(serverHost, pwd string, dbIndex int) *redisC {
// 注意:响应参数也是函数内的局部变量
setDb := redis.DialDatabase(dbIndex)
setPassword := redis.DialPassword(pwd)
conn, err := redis.Dial("tcp", serverHost, setDb, setPassword)
if err != nil {
fmt.Println("conn redis error", err)
return nil
}
return &redisC{Conn: conn}
}
func (r *redisC) SetValue(key, value interface{}) error {
_, err := r.Conn.Do("set", key, value)
return err
}
func (r *redisC) GetValue(key interface{}) string {
v, err := redis.String(r.Conn.Do("get", key))
if err != nil {
fmt.Printf("未找到key【%s】\n", key)
return ""
}
return v
}
主程序: string类型 get set操作,调用封装好的两个结构体指针方法
package main
import (
"fmt"
"test_mysql/redisC"
)
const (
serverHost = "host:port"
)
func main() {
// 1. 初始化redis客户端
redisClient := redisC.InitRedis(serverHost, "password", 0)
// 关闭redis客户端链接
defer redisClient.Conn.Close()
// 设置键值对
redisClient.SetValue("name", "15")
// 获取键对应的值
s := redisClient.GetValue("name")
fmt.Println(s)
}
3. string 批量操作:新增两个redisC结构体指针方法即可
func (r *redisC) MSet(keysValues...interface{}) error { // 批量设置键值对 _, err := r.Conn.Do("MSet", keysValues...) if err != nil { return err } return nil } func (r *redisC) MGet(keys ...interface{}) []string { // 批量获取键值对 s, err := redis.Strings(r.Conn.Do("MGet", keys...)) if err != nil { return nil } return s }
4. 设置过期时间,继续增加redisC结构体指针方法
func (r *redisC) Expire(key interface{}, expire int) { // 设置过期时间 _, err := r.Conn.Do("expire", key, expire) if err != nil { fmt.Println("expire fail", err) return } }
5. list队列操作
func (r *redisC) LPush(values ...interface{}) { // 往队列里添加数据 _, err := r.Conn.Do("lpush", values...) if err != nil { fmt.Println(err) return } } func (r *redisC) RPop() interface{} { // 从队列里弹出数据 v, err := redis.String(r.Conn.Do("rpop", "哈哈")) if err != nil { fmt.Println(err) return nil } return v }
6. 设置hash 和 获取hash属性的值
func (r *redisC) HSet(objKeyValues ...interface{}) { // 设置hash _, err := r.Conn.Do("HSet", objKeyValues...) if err != nil { fmt.Println("HSet fail", err) return } } func (r *redisC) HGet(objKey ...interface{}) interface{} { // 获取hash属性的值 value, err := redis.String(r.Conn.Do("HGet", objKey...)) if err != nil { fmt.Println("HSet fail", err) return nil } return value }
7. redisC结构体指针的所有方法
package redisC import ( "fmt" "github.com/gomodule/redigo/redis" ) type redisC struct { Conn redis.Conn } func InitRedis(serverHost, pwd string, dbIndex int) *redisC { // 注意:响应参数也是函数内的局部变量 setDb := redis.DialDatabase(dbIndex) setPassword := redis.DialPassword(pwd) conn, err := redis.Dial("tcp", serverHost, setDb, setPassword) if err != nil { fmt.Println("conn redis error", err) return nil } return &redisC{Conn: conn} } func (r *redisC) SetValue(key, value interface{}) error { // 设置单个键值对 _, err := r.Conn.Do("set", key, value) return err } func (r *redisC) GetValue(key interface{}) string { // 获取单个键值对 v, err := redis.String(r.Conn.Do("get", key)) if err != nil { fmt.Printf("未找到key【%s】\n", key) return "" } return v } func (r *redisC) MSet(keysValues...interface{}) error { // 批量设置键值对 _, err := r.Conn.Do("MSet", keysValues...) if err != nil { return err } return nil } func (r *redisC) MGet(keys ...interface{}) []string { // 批量获取键值对 s, err := redis.Strings(r.Conn.Do("MGet", keys...)) if err != nil { return nil } return s } func (r *redisC) Expire(key interface{}, expire int) { // 设置过期时间 _, err := r.Conn.Do("expire", key, expire) if err != nil { fmt.Println("expire fail", err) return } } func (r *redisC) LPush(values ...interface{}) { // 往队列里添加数据 _, err := r.Conn.Do("lpush", values...) if err != nil { fmt.Println(err) return } } func (r *redisC) RPop() interface{} { // 从队列里弹出数据 v, err := redis.String(r.Conn.Do("rpop", "哈哈")) if err != nil { fmt.Println(err) return nil } return v } func (r *redisC) HSet(objKeyValues ...interface{}) { // 设置hash _, err := r.Conn.Do("HSet", objKeyValues...) if err != nil { fmt.Println("HSet fail", err) return } } func (r *redisC) HGet(objKey ...interface{}) interface{} { // 获取hash属性的值 value, err := redis.String(r.Conn.Do("HGet", objKey...)) if err != nil { fmt.Println("HSet fail", err) return nil } return value }
8. 主程序调用结构体指针方法实现操作redis数据库
package main import ( "fmt" "test_mysql/redisC" ) const ( serverHost = "host:port" ) func main() { // 1. 初始化redis客户端 redisClient := redisC.InitRedis(serverHost, "password", 0) // 关闭redis客户端链接 defer redisClient.Conn.Close() // 设置键值对 redisClient.SetValue("name", "张三") // 获取键对应的值 fmt.Println(redisClient.GetValue("name")) // 张三 // 批量设置键值 redisClient.MSet("age", 88, "sex", "male") // 批量获取键值 fmt.Println(redisClient.MGet("name", "age", "sex", "gender")) // [张三 88 male ] // 设置过期时间 redisClient.Expire("sex", 30) // lpush+rpop实现了一个队列:先进先出 // list:lpush 往队列里添加数据 redisClient.LPush("哈哈", 123) redisClient.LPush("哈哈", 456) // list:lpop 从队列里弹出数据 fmt.Println(redisClient.RPop()) // 设置hash //redisClient.HSet("book", "price", 100, "title", "三宽") // 获取hash fmt.Println(redisClient.HGet("book", "price")) }
9. redis 连接池的使用
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) const ( serverHost = "host:port" ) var pool *redis.Pool func init() { setDb := redis.DialDatabase(0) setPassword := redis.DialPassword("password") pool = &redis.Pool{ // 实例化一个连接池结构体指针 MaxIdle: 16, // 最初的连接数量 //MaxActive: 1000000, // 最大连接数量 MaxActive: 0, // 连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配 IdleTimeout: 300, // 连接关闭时间 300 秒(300秒不使用自动关闭) Dial: func() (redis.Conn, error) { // 要链接的redis数据库 return redis.Dial("tcp", serverHost, setDb, setPassword) }, } } func main() { conn := pool.Get() // 从连接池取一个连接 defer conn.Close() // 函数运行结束,把链接放回连接池 value, err := redis.String(conn.Do("get", "age")) if err != nil { fmt.Println(err) return } fmt.Println(value)
// 最后关闭连接池 pool.Close() }