0%

go操作redis

说明

本次主要时在windows下,利用go 操作redis

redis

概述

  • Redis(Remote Dictionary Server ),即远程字典服务,它是一个开源的,使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis 默认端口为 6379,是一个NoSQL数据库

安装

  • 打开地址下载安装包并安装,安装成功后在环境变量中可以看到,安装目录已经加入到了PATH中

启动服务端

  • 执行命令启动服务端
1
2
D:\app\Redis>redis-server.exe redis.windows.conf
[6436] 10 Jul 17:44:10.177 # Creating Server TCP listening socket *:6379: bind: No error
  • 查看服务端口是否正常
1
2
3
D:\app\Redis>netstat -an | findstr "6379"
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING
TCP [::]:6379 [::]:0 LISTENING

启动客户端

打开redis目录中的redis.windows.conf

  • 配置Redis的设置最大占用内存,设置maxmemory参数,maxmemory是字节字节类型,如果不设置maxmemory或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。
1
2
3
# maxmemory <bytes>
# 设置最大的内存为1G
maxmemory 1000000000
  • 执行命令
1
D:\app\Redis>redis-cli.exe -h 127.0.0.1 -p 6379
  • 进行set和get操作
1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> set username hello
OK
127.0.0.1:6379> get username
"hello"
127.0.0.1:6379>SCAN 0 MATCH * // 查询所有key
127.0.0.1:6379> FLUSHDB //删除所有Key
127.0.0.1:6379> keys * // 查询所有key
1) "cache:user:id:23"
127.0.0.1:6379> del "cache:user:id:admin" // 删除指定key
(integer) 1

go

实现

  • 使用gin框架

  • 自定义Person结构体

  • 实现对Person的增删改查。

  • 根据id查询或查询所有、插入、修改、删除

代码

  • 先安装依赖文件
1
2
go get -u github.com/gin-gonic/gin
go get github.com/redis/go-redis/v9
  • 新建并初始化项目
1
2
3
4
cd E:\proj\gowork
mkdir studyGin
cd studyGin
go mod init example.com/goRedis
  • 用vscode ide编写代码
  • db\dbs.go 主要存放连接redis的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package db

import (
"context"
"fmt"

"github.com/redis/go-redis/v9"
)

var Rdbs *redis.Client

func InitRedis(ctx context.Context) {
rd := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
Rdbs = rd
//清空当前数据库中的所有key,只要加了这个每次重新启动服务器,所有数据被清空
// Rdbs.FlushDB(ctx)
_, err := Rdbs.Ping(ctx).Result() // PING, <nil>
if err != nil {
fmt.Println("connect redis failed:", err)
return
}

}
func Close() {
Rdbs.Close()
}


  • model\users.go 操作user的实体类,如曾删改查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package models

import (
"context"
"encoding/json"
"fmt"

"example.com/goRedis/db"
)

type User struct {
Key string `json:"key"`
Name string `json:"name"`
Password string `json:"password"`
Id int `json:"id"`
}

// 存储和读取redis时,不能直接存入结构体,必须进行序列号和反序列化

// 序列化
func (u *User) MarshalBinary() (data []byte, err error) {
return json.Marshal(u)
}

// 反序列化
func (u *User) UnmarshalBinary(data []byte) (err error) {
return json.Unmarshal(data, u)
}

// 新增数据
func (u *User) Add(ctx *context.Context) (err error) {

// HMSet 批量设置 map[string]interface{}{"name": "张", "password": "11111", "id": 123}

fmt.Println("json.=", u)
// 必须转为[]byte, redis不支持直接存结构体

// 0 表示key永不过期
_, err = db.Rdbs.Set(*ctx, u.Key, u, 0).Result()
if err != nil {
fmt.Println("db.Rdbs.Set,", err)
return
}
return
}

// 根据key 获取到数据
func (u *User) GetUser(ctx *context.Context) (user1 User, err error) {

err = db.Rdbs.Get(*ctx, u.Key).Scan(u)
if err != nil {
fmt.Println("GetUser error", err)
return
}
user1 = *u
return
}

// 查询所有
func (u *User) QueryAll(ctx *context.Context) (user1 []User, er error) {
// keys, err := db.Rdbs.Keys(*ctx, "[1-9]*")).Result()
keys, err := db.Rdbs.Keys(*ctx, "*").Result()
fmt.Println("key=", keys)
if err != nil {
fmt.Println("db.Rdbs.Keys error:", err)
return
}
for _, key := range keys {
err = db.Rdbs.Get(*ctx, key).Scan(u)
if err != nil {
fmt.Print("Rdbs.Get error", err)
fmt.Println("key=", key)
return
}
fmt.Println("query=", *u)
user1 = append(user1, *u)

}
return
}

// 删除
func (u *User) DeleteUser(ctx *context.Context) (err bool) {
// 先判断key是否存在
if db.Rdbs.Exists(*ctx, u.Key).Val() == 1 {
_, er := db.Rdbs.Del(*ctx, u.Key).Result()
if er != nil {
fmt.Println("DeleteUser error: ", err)
return false
}
return true
}
return false
}

// 修改
func (u *User) UpdateUser(ctx *context.Context) (err error) {
// 先判断key是否存在
if db.Rdbs.Exists(*ctx, u.Key).Val() == 1 {
// 必须转为[]byte, redis不支持直接存结构体
u1, _ := json.Marshal(u)
_, err = db.Rdbs.Set(*ctx, u.Key, u1, 0).Result()
if err != nil {
fmt.Println("UpdateUser error:", err)
return
}
}
return
}


  • api/users.go 调用model层代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package api

import (
"context"
"fmt"
"net/http"

"example.com/goRedis/models"
"github.com/gin-gonic/gin"
)

func UserAdd(c *gin.Context, ctx *context.Context) {
fmt.Println("add=", c)
var user models.User
if c.Bind(&user) == nil { //把客户端格式传过来的数据绑定到结构体user中去
fmt.Println("data=", user)
err := user.Add(ctx) // 调用model层的对应方法
if err != nil {

c.JSON(http.StatusOK, gin.H{
"msg": "新增失败",
"code": -1,
})

} else {
c.JSON(http.StatusOK, gin.H{
"msg": "新增成功",
"code": 1,
})
}
} else {
c.JSON(400, gin.H{"JSON=== status": "binding JSON error!"})
}
}

func UserGet(c *gin.Context, ctx *context.Context, key string) {
// 接受key
users := models.User{
Key: key,
}
if c.Bind(&users) == nil {
users, err := users.GetUser(ctx)
if err != nil {

c.JSON(http.StatusOK, gin.H{
"msg": "获取失败",
"code": -1,
"user": users,
})

} else {
c.JSON(http.StatusOK, gin.H{
"msg": "获取成功",
"code": 1,
"user": users,
})
}
} else {
c.JSON(400, gin.H{"JSON=== status": "binding JSON error!"})
}
}

func UserAll(c *gin.Context, ctx *context.Context) {
var user models.User
if c.Bind(&user) == nil {
users, err := user.QueryAll(ctx)
if err != nil {

c.JSON(http.StatusOK, gin.H{
"msg": "获取失败",
"code": -1,
"user": users,
})

} else {
c.JSON(http.StatusOK, gin.H{
"msg": "获取成功",
"code": 1,
"user": users,
})
}
} else {
c.JSON(400, gin.H{"JSON=== status": "binding JSON error!"})
}
}

func UserDel(c *gin.Context, ctx *context.Context) {
var user models.User
if c.Bind(&user) == nil {
err := user.DeleteUser(ctx)
fmt.Println("del=", err)
if !err {

c.JSON(http.StatusOK, gin.H{
"msg": "删除失败1",
"code": -1,
})

} else {
c.JSON(http.StatusOK, gin.H{
"msg": "删除成功1",
"code": 1,
})
}
} else {
c.JSON(400, gin.H{"JSON=== status": "binding JSON error!"})
}
}

func UserUpdate(c *gin.Context, ctx *context.Context) {
var user models.User
if c.Bind(&user) == nil {
err := user.UpdateUser(ctx)
if err != nil {

c.JSON(http.StatusOK, gin.H{
"msg": "修改失败",
"code": -1,
})

} else {
c.JSON(http.StatusOK, gin.H{
"msg": "修改成功",
"code": 1,
})
}
} else {
c.JSON(400, gin.H{"JSON=== status": "binding JSON error!"})
}
}

  • main.go 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
"context"

"example.com/goRedis/api"
"example.com/goRedis/db"
"github.com/gin-gonic/gin"
)

func main() {
ctx := context.Background()
db.InitRedis(ctx)
defer db.Close()
r := gin.Default()
r.POST("/userAdd", func(c *gin.Context) {
api.UserAdd(c, &ctx)
})
r.GET("/userAll", func(c *gin.Context) {
api.UserAll(c, &ctx)
})
r.GET("/userGet/:key", func(c *gin.Context) {
key := c.Param("key")

api.UserGet(c, &ctx, key)
})
r.POST("/userUpdate", func(c *gin.Context) {
api.UserUpdate(c, &ctx)
})
r.POST("/userDel", func(c *gin.Context) {
api.UserDel(c, &ctx)
})
r.Run(":8000")
}

客户端

  • 使用python调用服务端代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
data ={"name": "test11", "password": "1123456", "id": 1, "key": "t_key1"}
resp = requests.post("http://127.0.0.1:8000/userAdd", json=data)
print(resp.text)
resp = requests.get("http://127.0.0.1:8000/userGet/t_key2")
print(resp.text)

resp = requests.get("http://127.0.0.1:8000/userAll")
print(resp.text)


data ={"name": "test1131", "password": "123456811", "id": 111, "key": "t_key21"}
resp = requests.post("http://127.0.0.1:8000/userUpdate", json=data)
print(resp.text)

data ={"key": "t_key1"}
resp = requests.post("http://127.0.0.1:8000/userDel", json=data)
print(resp.text)

其他