redis在go语言中的使用
以下说明以读者有redis基础的前提下进行
未学习redis的可以到b站1小时浅学redis了解大概,学会如何使用
【GeekHour】一小时Redis教程_哔哩哔哩_bilibili
以下开发环境以windows为测试环境,旨在练习redis在go语言中的使用
redis使用的是5.0.14的windows版本(正常开发项目redis都是在linux上使用,windows的redis版本很低),但基础功能都有,满足学习要求;
下载链接:https://github.com/tporadowski/redis/releases
(官网是没有windows版本的)
下载完成后,打开黑窗口,输入redis-cli显示
即为成功,可以选择性下载redis的gui工具redisInsight,官网链接:
RedisInsight | The Best Redis GUI
使用时截图:
左侧会显示key,点击后右侧会显示value的值,使用和查找起来较为方便,能够增加学习效率,当然还有很多功能,这里就不赘述
1引入go-redis库
为什么使用这个库,而不是其他的库呢?
理由:
- 性能高效: Go-Redis实现了高性能的Redis客户端,具有低延迟和高吞吐量。它采用了异步的方式处理多个并发请求,从而提高了性能。
- 完整支持Redis功能: Go-Redis库提供了对Redis的全面支持,包括对基本数据结构(字符串、哈希、列表、集合等)的操作,事务,流水线(pipeline)等功能。
- 易用性: Go-Redis提供了简单而直观的API,易于使用。它封装了与Redis的底层通信细节,使得开发者可以专注于业务逻辑而不必过多关注底层实现。
- 连接池: Go-Redis包含了连接池的支持,这有助于有效地管理和复用与Redis的连接,减少了连接的创建和销毁开销,提高了性能。
- Active development和社区支持: Go-Redis是一个活跃的项目,有一个庞大的社区支持。这意味着它经常得到更新和改进,并且有丰富的文档和社区资源可供参考。
- 灵活性: Go-Redis允许开发者选择不同的执行模式,如同步、异步和流水线,以满足不同场景下的需求。
总之,这个库用的人多,并且功能齐全,很适合在go语言中与redis交互;(好用就完事了!!!)
2在go项目中的初始化
其实很简单,和mysql初始化优点相似;
为了方便学习,初始化都写在一个文件中
如下:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
// 创建一个新的Redis客户端实例
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379", // Redis服务器地址
Password: "", // 可选:如果有密码的话
DB: 0, // 使用的数据库编号
})
// 使用Ping测试连接
pong, err := client.Ping(context.Background()).Result()
if err != nil {
fmt.Println("连接Redis出错:", err)
return
}
fmt.Println("连接成功,Ping结果:", pong)
// 在程序结束时关闭连接
defer client.Close()
// 在这里可以继续执行其他与Redis相关的操作
}
测试运行成功会输出:
连接成功,Ping结果: PONG
基础键值对相关操作
在go中简单设置键值对并查找键值对
简单设置一个键值对,来试试是否能够查找成功:
在go中设置key方法:Set
// 生成测试用的key
testKey := "test_key"
// 设置key的值,演示Set方法
err = client.Set(context.Background(), testKey, "Hello, Redis!", 0).Err()
if err != nil {
fmt.Println("设置key出错:", err)
return
}
fmt.Println("设置key成功")
//解释:
//通过创建testKey变量,你定义了一个测试用的键。
//使用client.Set方法设置了键test_key的值为字符串"Hello, Redis!",并指定了过期时间为0,表示不设置过期时间。
//通过检查错误(err != nil)来确保设置操作是否成功。如果设置失败,你输出了错误信息;否则,你输出了"设置key成功"。
检测key对应的value的值的方法:Get
// 获取key的值,演示Get方法
value, err := client.Get(context.Background(), testKey).Result()
//result作用是:等待并返回实际的 Redis 命令执行结果。 这种异步操作和等待结果的方式有助于确保代码在获取 Redis 操作结果时不会阻塞整个程序,以便更好地处理并发性能。
if err != nil {
fmt.Println("获取key出错:", err)
return
}
fmt.Printf("获取key的值:%s\n", value)
}
//成功运行时会返回:
//获取key的值:Hello, Redis!
redisInsight截图:
获取指定键的当前值并设置一个新的值:GetSet
// 使用 GETSET 获取testKey原有的值存入到oldValue中,并设置新值为NewValue
oldValue, err := client.GetSet(context.Background(), testKey, "NewValue").Result()
if err != nil {
fmt.Println("GETSET 操作出错:", err)
return
}
fmt.Printf("旧值:%s\n", oldValue)
// 获取更新后testKey中的值并存到newValue中
newValue, err := client.Get(context.Background(), testKey).Result()
if err != nil {
fmt.Println("获取key出错:", err)
return
}
fmt.Printf("新值:%s\n", newValue)
其实还是很简单的,都是一些重复代码段;
批量设置key的值:MSet
// 准备要设置的键值对
keyValues := map[string]interface{}{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
// 使用 MSet 方法批量设置键值对
err = client.MSet(context.Background(), keyValues).Err()
if err != nil {
fmt.Println("批量设置键值对出错:", err)
return
}
//这个M的意思其实是mutiple(多个),不止针对普通string,对于HGet等等都能变成HMGet,批量增加
成功
增加整数的值的两个方法:Incr,Incrby
前者可以将值每次增加1,当要增加的值不存在时,会先自动置为0进行操作。下例就是
// 示例使用的键名
key := "myKey"
// 使用 INCR 递增键的值, myKey初值为空,自动置为0+1了
newValue, err := client.Incr(context.Background(), key).Result()
if err != nil {
fmt.Println("INCR 操作出错:", err)
return
}
fmt.Printf("INCR 后 %s 的值为 %d\n", key, newValue)
// 使用 INCRBY 指定增量递增键的值 1+5=6;
increment := 5
newValue, err = client.IncrBy(context.Background(), key, int64(increment)).Result()
if err != nil {
fmt.Println("INCRBY 操作出错:", err)
return
}
fmt.Printf("INCRBY %d 后 %s 的值为 %d\n", increment, key, newValue)
在实际开发中还是要看需要什么用什么
设置过期时间
之前的Set方法中,最后一个参数是0,表示的就是过期时间设置,默认以秒为单位,当为0时,表示永不过期,写10,就是10s后过期,写其他单位的数字就需要加单位,如1*time.Minute就是1分钟;
而正规一点的过期时间设置方法是:
使用Expire方法:直接设置key在生成后多少时间过期,比如10秒后过期
// 设置 key 的值
err := client.Set(context.Background(), "myKey", "myValue", 0).Err()
if err != nil {
fmt.Println("设置 key 的值出错:", err)
return
}
// 给 key 设置过期时间为 10 秒
err = client.Expire(context.Background(), "myKey", 10*time.Second).Err()
if err != nil {
fmt.Println("给 key 设置过期时间出错:", err)
return
}
使用ExpireAt方法:表示过期的具体时间点,比如直接写成25年的1月1号0点0分过期;
// 设置 key 的值
err := client.Set(context.Background(), "myKey", "myValue", 0).Err()
if err != nil {
fmt.Println("设置 key 的值出错:", err)
return
}
// 给 key 设置过期时间为 10 秒后的某个特定时间
expirationTime := time.Now().Add(10 * time.Second)
err = client.ExpireAt(context.Background(), "myKey", expirationTime).Err()
if err != nil {
fmt.Println("给 key 设置过期时间出错:", err)
return
}
哈希键值对操作:
HGet
先举个例子方便理解,比如,原来的Get命令只能生成简单的键值对,但使用HGet,可以将多个键值对变成同一个哈希表对应的键值对,例如:
这样就清楚了吧,代码示例:
创建和获取哈希类型
// 准备哈希名、字段和值
hashName := "user:1"
fieldName := "username"
fieldValue := "JohnDoe"
// 使用 HSet 方法设置哈希字段的值
err := client.HSet(context.Background(), hashName, fieldName, fieldValue).Err()
if err != nil {
fmt.Println("设置哈希字段的值出错:", err)
return
}
// 使用 HGet 方法获取哈希字段的值
result, err := client.HGet(context.Background(), hashName, fieldName).Result()
if err != nil {
fmt.Println("获取哈希字段的值出错:", err)
return
}
批量创建哈希类型中的键值对
一看就会
// 准备哈希名
hashName := "user:1"
// 使用 HMSet 一次性设置多个键值对
keyValueMap := map[string]interface{}{
"username": "JohnDoe",
"email": "john@example.com",
"age": "30",
}
err := client.HMSet(context.Background(), hashName, keyValueMap).Err()
if err != nil {
fmt.Println("一次性设置多个键值对出错:", err)
return
}
fmt.Printf("成功一次性设置多个键值对到哈希表 %s\n", hashName)
}