个人使用的redis是使用docker在容器中运行的。
# 使用docker拉取redis镜像
[root@bogon /]# docker pull redis:latest
latest: Pulling from library/redis
Digest: sha256:89051d5ec46a89d4a708467af38eaaf4029450c4b1b9835ffd413cf70625b22e
Status: Image is up to date for redis:latest
docker.io/library/redis:latest
# 运行镜像
[root@bogon /]# docker run -tid --name redis_local -p 6379:6379 redis:latest
e60b37960034
# 查看镜像
[root@bogon /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e60b37960034 redis:latest "docker-entrypoint.s…" 2 days ago Up About an hour 0.0.0.0:6379->6379/tcp redis_local
ba6b74098ebd registry.hangjia.online/base/mysql:5.7 "docker-entrypoint.s…" 4 days ago Up About an hour 0.0.0.0:3306->3306/tcp, 33060/tcp mysql5.7
本人使用 go mod 管理项目依赖包(和包版本)管理
如果是初始项目,在项目根目录下执行
# 在项目目录下初始化 go mod
go mod init
# 下载 go-redis 依赖
go get github.com/go-redis/redis/v8
go-redis 源码
项目中引入 go-redis 包,初始化 redis 客户端
package service
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var RedisClient *redis.Client
// 初始化 redis
func NewRedisClient() (*redis.Client, error) {
RedisClient = redis.NewClient(&redis.Options{
Addr: "192.168.0.74:6379", // 要连接的redis IP:port
Password: "", // redis 密码
DB: 0, // 要连接的redis 库
})
// 检测心跳
pong, err := RedisClient.Ping(context.Background()).Result()
if err != nil {
fmt.Println("connect redis failed")
return nil, err
}
fmt.Printf("redis ping result: %s\n", pong)
return RedisClient, nil
}
Ping() 旧版本是不需要参数的,v8 需要参数 context.Context
本人对 go-redis 做了基本封装
package service
import (
"context"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
/*
向 redis hash 中存值
参数:
key:存入hash的key值
mapData:对应key的map值
mapData 格式: map[string]interface{}{"key1": "value1", "key2": "value2"}
return:bool(是否添加成功),error(错误信息)
*/
func HashSet(key string, mapData map[string]interface{}) (bool, error) {
// 参数非空验证
if key == "" || mapData == nil {
fmt.Println("key===>", key)
fmt.Println("mapData===>", mapData)
return false, errors.New("参数为空")
}
fmt.Println("key===>", key)
fmt.Println("mapData===>", mapData)
if RedisClient == nil {
fmt.Println("客户端为空")
return false, errors.New("客户端断开连接")
} else {
if err := RedisClient.HSet(ctx, key, mapData).Err(); err != nil {
return false, errors.New("添加失败")
} else {
return true, nil
}
}
}
/*
根据key,field 获取值
参数:
key:存入hash的key值
field:字段名
return:string(返回字段的值),error(错误信息)
*/
func HashGet(key string, field string) (string, error) {
// 参数非空判断
if key == "" || field == "" {
return "", errors.New("参数为空")
}
value, err := RedisClient.HGet(ctx, key, field).Result()
if err == redis.Nil {
return "", errors.New("key 不存在")
} else if err != nil {
return "", errors.New("获取失败")
}
return value, nil
}
/*
根据key,field 获取值
参数:
key:存入hash的key值
fields:可变长参数,0到n个field
return:map[string]interface{} 返回一个map
*/
func BatchHashGet(key string, fields ...string) ([]interface{}, error) {
if key == "" {
return nil, errors.New("参数为空")
}
resultArray, err := RedisClient.HMGet(ctx, key, fields...).Result()
if err != nil {
return nil, errors.New("error occur when get data from redis : " + err.Error())
}
return resultArray, nil
}
/*
判断 hash key,field是否存在
参数:
key:存入hash的key值
field:字段名
返回值:
bool:字段是否存在
error:错误信息
*/
func HashKeyExist(key, field string) (bool, error) {
if key == "" || field == "" {
return false, errors.New("参数为空")
}
b, err := RedisClient.HExists(ctx, key, field).Result()
if err != nil {
return false, errors.New("异常:" + err.Error())
}
return b, nil
}
/*
删除hash field
参数:
key:存入hash的key值
fields:字段名 数组
返回值:
bool:字段是否存在
error:错误信息
*/
func HashDel(key string, fields ...string) (bool, error) {
if key == "" {
return false, errors.New("参数为空")
}
r, err := RedisClient.HDel(ctx, key, fields...).Result()
if err != nil {
return false, errors.New("异常:" + err.Error())
}
fmt.Println("删除hash key :", r)
return true, nil
}
# 使用test单元测试
package test
import (
"context"
"fmt"
"testing"
"time"
"com.hangjia/ych/myadmin/service"
"github.com/go-redis/redis/v8"
)
func TestRedis(t *testing.T) {
// 初始化 redis
service.InitRedisClient()
if service.RedisClient == nil {
fmt.Println("========================= redis client is nil ===================")
panic("redis client is nil")
}
ctx := context.Background()
// 准备测试数据
var mapData map[string]interface{}
mapData = make(map[string]interface{})
mapData["name"] = "test_ex"
mapData["age"] = 110
// 判断 key field 是否存在
b, err := service.HashKeyExist("110", "name")
if err != nil {
fmt.Println("判断key是否存在,异常:", err)
} else {
fmt.Println("判断key是否存在 ", b)
}
// 删除
if b {
b1, err := service.HashDel("110", "name")
if err != nil {
fmt.Println("hash 删除,异常:", err)
}
fmt.Println("删除,", b1)
}
// redis hash set
b, err = service.HashSet("110", mapData)
if err != nil {
fmt.Println("redis 插入失败")
}
fmt.Println("redis 插入", b)
// redis hash get
s, err := service.HashGet("110", "name")
if err != nil {
fmt.Println("redis :", err)
}
fmt.Println("110 :", s)
// redis hash mget
param := []string{"name", "age"}
resultArray, err := service.BatchHashGet("110", param...)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("resultArray:===>", resultArray)
}
fmt.Println("========================= set =========================")
// redis set 过期时间
err = service.RedisClient.Set(context.Background(), "text_nx", "textnx_value", time.Second*30).Err()
if err != nil {
fmt.Println("set设置过期时间失败", err)
} else {
fmt.Println("set设置过期时间成功")
}
// 获取过期时间
var time time.Duration
time, err = service.RedisClient.TTL(ctx, "text_nx").Result()
fmt.Println("text_nx 过期时间为:", time)
// redis set 取值
var value string
value, err = service.RedisClient.Get(context.Background(), "text_nx").Result()
if err == redis.Nil {
fmt.Println("key not exists")
} else if err != nil {
fmt.Println("get value from key err :===>", err)
} else {
fmt.Println("get value from key is :===>", value)
}
}