1.安装与连接
1.1安装
go get github.com/redis/go-redis/v9
2.连接Redis
2.1创建 Redis 客户端连接
rdb = redis.NewClient(&redis.Options{...}):这行代码调了 redis 库中的 NewClient 函数来创建一个新的 Redis 客户端实例,并将其赋值给变量 rdb
rdb = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
传递给 NewClient 函数的是一个 redis.Options 结构体的实例,用于配置 Redis 客户端的连接选项:
Addr: "localhost:6379":指定了 Redis 服务器的地址和端口号。这里设置为本地主机(localhost)的默认 Redis 端口6379,意味着客户端将会尝试连接到本地运行的 Redis 服务器实例。Password: "":设置连接 Redis 服务器的密码。这里为空字符串,表示没有设置密码,将以默认的无密码方式进行连接。如果 Redis 服务器设置了密码保护,就需要在此处填写正确的密码才能成功连接。DB: 0:指定要连接的 Redis 数据库编号。Redis 可以支持多个数据库(通常从 0 开始编号),这里设置为 0,表示连接到默认的数据库 0。不同的数据库可以用于隔离不同应用程序或业务场景的数据存储需求。
3.操作Redis
3.1 String类型
package main
import (
"fmt"
"github.com/go-redis/redis"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.Set("name", "Alice", 0).Err()
if err!= nil {
fmt.Println("设置键值对出错:", err)
} else {
fmt.Println("键值对设置成功")
}
val, err := rdb.Get("name").Result()
if err!= nil {
fmt.Println("获取值出错:", err)
} else {
fmt.Println("获取到的值为:", val)
}
err := rdb.MSet("age", 20, "city", "New York").Err()
if err!= nil {
fmt.Println("批量设置键值对出错:", err)
} else {
fmt.Println("批量设置键值对成功")
}
err := rdb.Set("count", 5, 0).Err()
if err!= nil {
fmt.Println("设置初始计数出错:", err)
}
val, err := rdb.Incr("count").Result()
if err!= nil {
fmt.Println("自增计数出错:", err)
} else {
fmt.Println("自增后的计数为:", val)
}
count, err := rdb.Del("name").Result()
if err!= nil {
fmt.Println("删除键出错:", err)
} else {
fmt.Println("删除了", count, "个键")
}
result, err := rdb.SetNX("fruit", "Apple", 0).Result()
if err!= nil {
fmt.Println("设置键值对出错:", err)
} else if result {
fmt.Println("键不存在,设置成功")
} else {
fmt.Println("键已存在,未进行设置")
}
}
解释:
- 首先创建了一个 Redis 客户端连接对象
rdb。 - 然后使用
rdb.Set("name", "Alice", 0)尝试将键name的值设置为Alice。其中第三个参数0表示没有过期时间(永不过期) - 使用
rdb.Get("name").Result()来获取键name的值。 - 使用
rdb.MSet("age", 20, "city", "New York")一次性设置了两个键值对,分别是age - 20和city - New York。 - 使用
rdb.Incr("count").Result()对键count的值进行自增操作,返回自增后的结果并打印。 - 使用
rdb.Del("name").Result()删除键name,count返回被删除键的数量(这里如果键存在则为 1,不存在则为 0),根据err的值判断删除操作是否成功。 - 使用
rdb.SetNX("fruit", "Apple", 0).Result()尝试设置键值对。根据result的值判断是否设置成功(result为true表示设置成功,即键不存在;result为false表示键已存在,未进行设置),err用于判断操作过程是否出现错误。
Hash类型
- HSet HSet插入单个filed,且会自动创建不存在的key,同时也可以传入超时时间
go
代码解读
复制代码
_, err = rdb.HSet(ctx, "testHash1", "time", time.Now().Nanosecond()).Result()
- MSet HMSet一次插入多个filed,且会自动创建不存在的key。 其传入的多个数据类型需要用
map[string]interface{}包裹。
go
代码解读
复制代码
item := map[string]interface{}{"user_id": "2222", "got_digg_count": 1238, "follower_count": 379}
_, err := rdb.HMSet(ctx, "testHash1", item).Result()
- HGet HGet获取单个filed
go
代码解读
复制代码
val, _ := rdb.HGet(ctx, "testHash1", "user_id").Result()
- HGetAll HGetAll获取所有的key-vlue,Result()返回值类型为
map[string]string
go
代码解读
复制代码
items, _ := rdb.HGetAll(ctx, "testHash1").Result()
- HIncrBy HIncrBy实现哈希filed自增,将返回自增后的值,需要注意的是返回的值类型为
int64
go
代码解读
复制代码
val64, _ := rdb.HIncrBy(ctx, "testHash1", "user_id", 10).Result()
List类型
- LPush、RPush LPush、RPush向列表中插入多个值,L表示从左插入,R表示从右插入
go
代码解读
复制代码
rdb.LPush(ctx, "list1", 1, 2, 3, 4)
rdb.RPush(ctx, "list1", 5, 6, 7, 8)
- LInsert LInsert指定位置处插入值,并可以传入
"Before"或"After设置在该key前或后进行插入
go
代码解读
复制代码
rdb.LInsert(ctx, "list1", "Before", "2", 111)
- LIndex LIndex获取指定位置的值
go
代码解读
复制代码
val, _ := rdb.LIndex(ctx, "list1", 2).Result()
- BLPop、BRPop BLPop、BRPop分别表示从列表左侧弹出一个值和从列表右侧弹出一个值,相当于删除并返回。 需要传入的第一个参数表示阻塞模式的超时时间。命令会等待的最长时间。如果在超时时间内,列表中有可弹出的元素,则会立即返回该元素,否则在超时后返回空结果。 如果将超时时间设置为 0,则表示不进行超时等待,即如果列表为空,命令会一直阻塞等待直到有元素可以弹出。这种情况下,如果列表一直为空,命令会一直阻塞程序。
go
代码解读
复制代码
value, _ := rdb.BRPop(ctx, 0, "list1").Result()
value, _ = rdb.BLPop(ctx, 0, "list1").Result()
- LPopCount、RPopCount LPopCount、RPopCount表示从左侧或右侧弹出多个值,需要传入弹出值的数量,返回值为
[]string和error
go
代码解读
复制代码
items, _ = rdb.RPopCount(ctx, "list1", 2).Result()
Zset类型
2.4 Zset数据类型
- ZAdd ZAdd可以创建多条有序列表项。 通常借助
redis.Z创建数据,redis.Z结构体包含Score和Member字段,Score用于排序。
go
代码解读
复制代码
initList := []redis.Z{
{Member: "user1", Score: 10},
{Member: "user2", Score: 232},
{Member: "user3", Score: 129},
{Member: "user4", Score: 149},
{Member: "user5", Score: 122},
{Member: "user6", Score: 18},
{Member: "user7", Score: 12},
}
num, err := rdb.ZAdd(ctx, "zrank", initList...).Result()
上述代码中,initList...表示可变参数的展开,它的作用是将一个切片(或数组)的元素逐个展开,作为函数参数传递。
- ZRangeWithScores、ZRevRangeWithScores ZRangeWithScores、ZRevRangeWithScores 根据Score进行排序(正序或倒序)并返回指定范围内的项。Result()返回值类型为
[]redis.Z。
go
代码解读
复制代码
resList0, err := rdb.ZRevRangeWithScores(ctx, "zrank", 0, -1).Result()
- ZRangeArgsWithScores ZRangeArgsWithScores可以自定义排序规则和处理规则,需要借助
redis.ZRangeArgs这个结构体定义这些规则:
go
代码解读
复制代码
zRangeArgs := redis.ZRangeArgs{
Key: "zrank",
ByScore: true,
Rev: true,
Start: "-inf",
Stop: "+inf",
Offset: offset,
Count: pageSize,
}
resList1, err := rdb.ZRangeArgsWithScores(ctx, zRangeArgs).Result()
上述代码中,zRangeArgs结构体定义了offset和pageSize,offset表示数据排序的偏移量,pageSize表示获取的的数量最大值。Result()返回值类型为 []redis.Z。
- ZRank、ZRevRank ZRank、ZRevRank 分别以正序和逆序返回指定field的排名。
go
代码解读
复制代码
rank, err := rdb.ZRevRank(ctx, "zrank", "user1").Result()
- ZScore ZScore获取指定field的分值。
go
代码解读
复制代码
score, err := rdb.ZScore(ctx, "zrank", "user2").Result()