go-redis——入门

下载 Redis 的第三方库:go get github.com/go-redis/redis/v8
一.连接redis服务器
var rdb *redis.Client

var ctx = context.Background()

func RedisTest() {

	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

}

context.Context 对象是 Go 语言中用于管理请求范围值、取消信号和截止日期的机制。通过使用 context.Context 对象,可以将上下文相关的信息传递到应用程序的不同部分中,使得这些部分可以更加灵活地响应不同的情况。

在 Go-Redis 中,可以使用 context.Background() 创建一个 context.Context 对象,并将其作为参数传递给 Redis 操作的方法。这样可以允许对操作设置超时、取消等上下文相关的行为

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

// 执行 Redis 操作并设置超时时间
value, err := rdb.Get(ctx, "key").Result()
if err != nil {
    if err == redis.Nil {
        fmt.Println("Key does not exist")
    } else if err == context.DeadlineExceeded {
        fmt.Println("Operation timed out")
    } else {
        panic(err)
    }
} else {
    fmt.Println("Value:", value)
}

在上述示例中,我们使用 context.WithTimeout() 函数创建了一个带有截止日期的上下文,并将其作为参数传递给 Redis 操作。如果 Redis 操作的执行时间超过了指定的截止日期,操作将会被中止。 

二. get,set基本操作
func SetDemo() {
	// Set
	set := rdb.Set(ctx, "goland", "so good", 0)
	fmt.Println(set)
}

func GetDemo() {
	// Get
	res, err := rdb.Get(ctx, "goland").Result()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(res)
}

// SizeDemo 获取键值对数量失败
func SizeDemo() {
	count, err := rdb.DBSize(ctx).Result()
	if err != nil {
		fmt.Println("获取键值对数量失败:", err)
		return
	}

	fmt.Println("Redis 中存储的键值对数量是:", count)
}

// AllKey 获取 Redis 中所有的键名
func AllKey() {
	keys, err := rdb.Keys(ctx, "*").Result()
	if err != nil {
		fmt.Println("获取键名失败:", err)
		return
	}
	fmt.Println(keys)
	fmt.Println("Redis 中存储的键值对是:")
	//for _, key := range keys {
	//	value, err := rdb.Get(key).Result()
	//	if err != nil {
	//		fmt.Printf("读取键 %s 失败: %v\n", key, err)
	//	} else {
	//		fmt.Printf("%s : %s\n", key, value)
	//	}
	//}
}

// MsetDemo 批量设置
func MsetDemo() {
	err := rdb.MSet(ctx, "NO1", "Go", "NO2", "C++", "NO3", "JAVA", "NO4", "PYTHON").Err()
	if err != nil {
		fmt.Println("MSet failed, err: ", err)
		return
	}
}

// MgetDemo 批量获取
func MgetDemo() {
	res1, err := rdb.MGet(ctx, "NO1", "NO2", "NO3", "NO4").Result()
	if err != nil {
		fmt.Println(err)
		return
	}
	for i, _ := range res1 {
		fmt.Println(res1[i])
	}
}

// DelDemo 删除键值对
func DelDemo() {
	result, err := rdb.Del(ctx, "Chinese").Result()
	if err != nil {
		fmt.Println("删除键值对失败:", err)
		return
	}
	fmt.Println("已删除的键值对数量:", result)
}

// FlushAllDemo 清空所有键值对
func FlushAllDemo() {
	err := rdb.FlushAll(ctx).Err()
	if err != nil {
		fmt.Println("清空键值对失败:", err)
		return
	}

	fmt.Println("已清空所有键值对")
}
三.List,用来存储一个有序的字符串元素列表
// LpushDemo 从左边添加元素
//LPush 命令常用于构建队列、实现消息发布与订阅等场景,可以将新的元素插入到列表的头部,使得最新的元素在队列中的位置靠前。
func LpushDemo() {
	err := rdb.LPush(ctx, "NBAPlayer", "kobe", "kawhi").Err()
	if err != nil {
		fmt.Println("Push failed", err)
		return
	}
}

// LRangeDemo 获取list中所有元素
func LRangeDemo() {
	val := rdb.LRange(ctx, "NBAPlayer", 0, -1).Val()
	fmt.Println(val)
}

// LPopDemo 从list左边弹出一个元素
func LPopDemo() {
	res, err := rdb.LPop(ctx, "NBAPlayer").Result()
	if err != nil {
		fmt.Println("pop failed", err)
		return
	}
	fmt.Println(res)
}
四.Hash,它可以存储字段-值对的集合
// HSetDemo 添加或修改hash类型key的field的值
func HSetDemo() {
	err := rdb.HSet(ctx, "USA", "name", "dsb").Err()
	if err != nil {
		fmt.Println("Are you kidding? America Government is really sb")
		return
	}
}

// HGetDemo 获取一个hash类型的key的field的值
func HGetDemo() {
	res, err := rdb.HGet(ctx, "USA", "name").Result()
	if err != nil {
		fmt.Println("Are you kidding? America Government is really sb")
		return
	}
	fmt.Println(res)
}

// HMSetDemo 批量添加多个hash类型key的field值
func HMSetDemo() {
	usaMap := map[string]interface{}{"name": "dsb", "name2": "robber"}
	err := rdb.HMSet(ctx, "USA", usaMap).Err()
	if err != nil {
		fmt.Println("Are you kidding? America Government is really sb")
		return
	}
}

// HMGetDemo 批量获取hash类型key多个field的value值
func HMGetDemo() {
	res2 := rdb.HMGet(ctx, "USA", "name2", "name").Val()
	fmt.Println(res2)
}

// HGetAllDemo 获取哈希中的所有字段值
func HGetAllDemo() {
	hGetAll := rdb.HGetAll(ctx, "USA")
	if hGetAll.Err() != nil {
		panic(hGetAll.Err())
	}
	for field, value := range hGetAll.Val() {
		fmt.Println("name:", field)
		fmt.Println("name2:", value)
	}

}

// HDelDemo 删除哈希字段
func HDelDemo() {
	hDel := rdb.HDel(ctx, "USA", "name")
	if hDel.Err() != nil {
		panic(hDel.Err())
	}
}
五.Set,存储不重复的字符串元素的无序集合
// SAddDemo 向set中添加若干个元素
func SAddDemo() {
	err := rdb.SAdd(ctx, "Chinese", "AiGuo", "JingYe", "ChengXin", "YouShan").Err()
	if err != nil {
		fmt.Println("Are you right? Chinese people are really great", err)
		return
	}
}

// SMembersDemo 返回set中所有元素s
func SMembersDemo() {
	res3 := rdb.SMembers(ctx, "Chinese").Val()
	fmt.Println(res3)
}

// SIsMemberDemo 判断元素是否存在于set中
func SIsMemberDemo() {
	res4, err := rdb.SIsMember(ctx, "Chinese", "AiGuo").Result() // 这里返回的是bool
	if err != nil {
		fmt.Println("You're mistaken")
		return
	}
	fmt.Println("I can see that the Chinese are really AiGuo is", res4)
}

// SCardDemo 返回set中元素的个数
func SCardDemo() {
	count := rdb.SCard(ctx, "Chinese").Val()
	fmt.Printf("The Chinese people have %d virtues\n", count)
}

// SRemDemo 从集合中删除元素
func SRemDemo() {
	sRem := rdb.SRem(ctx, "Chinese", "JingYe")
	if sRem.Err() != nil {
		panic(sRem.Err())
	}
}
六.ZSet(有序集合)将字符串成员与浮点数分值相关联 
// ZAddDemo 向 ZSET 中添加元素
func ZAddDemo() {
	zAdd := rdb.ZAdd(ctx, "zset", 
		&redis.Z{Score: 90.0, Member: "Alice"},
		&redis.Z{Score: 80.0, Member: "Bob"})
	if zAdd.Err() != nil {
		panic(zAdd.Err())
	}
}

// ZRangeDemo 获取 ZSET 中的元素
func ZRangeDemo() {
	zRange := rdb.ZRange(ctx, "zset", 0, -1)
	if zRange.Err() != nil {
		panic(zRange.Err())
	}
	for _, member := range zRange.Val() {
		fmt.Println(member)
	}
}

// ZRemDemo 从 ZSET 中删除元素
func ZRemDemo() {
	zRem := rdb.ZRem(ctx, "zset", "Bob")
	if zRem.Err() != nil {
		panic(zRem.Err())
	}
}

// ZScoreDemo 获取指定元素的分值
func ZScoreDemo() {
	zScore := rdb.ZScore(ctx, "zset", "Alice")
	if zScore.Err() != nil {
		panic(zScore.Err())
	}
	fmt.Println("Score:", zScore.Val())
}

以下是 Redis 中常见数据类型的适用场景:

1. 字符串(String):字符串类型是最基本的数据类型,适用于存储任意类型的数据,例如用户信息、配置信息、计数器等。字符串类型可以设置过期时间,支持对字符串进行追加、覆盖和获取操作。

2. 哈希(Hash):哈希类型适用于存储对象、记录或配置等复杂数据结构。它提供了快速的字段查找和更新操作,可以对单个字段进行读写操作,也可以获取和修改整个哈希表。

3. 列表(List):列表类型适用于存储有序的字符串元素集合,可以在列表的两端进行元素插入和删除操作。它常用于消息队列、任务队列、最新消息列表等场景。

4. 集合(Set):集合类型适用于存储不重复的字符串元素的无序集合。集合提供了高效的成员检查和集合操作,可以用于存储唯一值、标签、关注者等场景。

5. 有序集合(Sorted Set):有序集合类型适用于存储不重复的字符串元素的有序集合。每个元素都关联着一个分数,可以根据分数进行排序。有序集合常用于排行榜、按权重排序的数据等场景。

七.pipeline

pipeline是一种提高数据处理效率的技术。Pipeline可以将多个Redis命令打包成一个请求发送给Redis服务器,减少了网络延迟和I/O开销,提高了数据处理效率。

func pipelineDemo() {
	//创建Pipeline对象
	pipe := rdb.Pipeline()
	//向Pipeline中添加Redis命令,与标准的go-redis命令用法相同
	pipe.Incr(ctx, "key")
	pipe.MGet(ctx, "key1", "key2", "key3")
	pipe.HSet(ctx, "hash", "field", "value")
	//执行Pipeline命令,一次性将所有Redis命令发送给Redis服务器执行
	_, err := pipe.Exec(ctx)
	if err != nil {
		// handle error
	}
	//在执行完Pipeline中的所有命令后,返回的结果是一个Redis命令结果数组,数组中的元素顺序对应Pipeline中添加的Redis命令顺序。
}
八.事务

go-redis库提供了事务功能,可以将多个命令组合在一起作为一个原子操作,保证数据的一致性和完整性

func TxPipelineDemo() {
	//创建一个事务对象
	tx := rdb.TxPipeline()
	defer tx.Close()
	//执行事务操作
	tx.Set(ctx, "key1", "value1", 0)
	tx.Set(ctx, "key2", "value2", 0)
	tx.Get(ctx, "key1")
	//提交事务
	_, err := tx.Exec(ctx)
	if err != nil {
		// 处理错误
	}
}
九.连接池
func pool() {
	// 创建 Redis 客户端
	client := redis.NewClient(&redis.Options{
		Addr:         "localhost:6379",
		Password:     "", // 如果有密码则填写
		PoolSize:     10, // 设置连接池大小为10
		MinIdleConns: 5,  // 设置最小空闲连接数为5
	})

	// 关闭连接池
	defer client.Close()

	// 获取连接
	conn := client.Conn(context.Background())

	// 关闭连接
	defer conn.Close()

	// 设置值
	err := conn.Set(context.Background(), "key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	// 获取值
	value, err := conn.Get(context.Background(), "key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(value)

}

你可能感兴趣的:(golang,redis,开发语言)