Go+Redis零基础到用户管理系统API实战_20240730 课程笔记
概述
如果您没有Golang的基础,应该学习如下前置课程。
- Golang零基础入门
- Golang面向对象编程
- Go Web 基础
- Go语言开发REST API接口_20240728
- Go语言操作MySQL开发用户管理系统API教程_20240729
- Redis零基础快速入门_20231227
基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。
视频课程
最近发现越来越多的公司在用Golang了,所以精心整理了一套视频教程给大家,这个是其中的第6部,后续还会有很多。
视频已经录制完成,完整目录截图如下:

本套课程的特色是每节课都是一个核心知识点,每个视频控制在十分钟左右,精简不废话,拒绝浪费大家的时间。
课程目录
- 01 概述
- 02 建立Redis连接对象
- 03 edis的打开和关闭方法
- 04 通过Do执行get和set命令
- 05 通过String自动转换字符串
- 06 通过Do实现mset和mget的操作
- 07 通过Do实现hset和hget的操作
- 08 通过Do实现lpush和lpop以及llen的操作
- 09 Redis的连接池介绍
- 10 Redis连接池的创建和使用
- 11 Redis的管道操作
- 12 Redis的事务操作
- 13 实现redigo的本地化
- 14 对zdpgo_redis的包结构进行调整
- 15 发布zdpgo_redisv1.1.0版本
- 16 新增用户
- 17 修改用户
- 18 删除用户
- 19 查询所有用户
- 20 实现查询所有用户的接口并进行测试
- 21 实现新增用户的接口并进行测试
- 22 解决ID唯一性的问题
- 23 实现修改用户的接口并进行测试
- 24 实现删除用户的接口并进行测试
- 25 实现根据ID查询用户的接口并进行测试
- 26 总结
完整代码
01 概述
02 建立Redis连接对象
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)func main() {r, err := redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}defer r.Close()
}
03 edis的打开和关闭方法
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()fmt.Println("主程序的操作。。。")
}
04 通过Do执行get和set命令
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()// set 操作_, err = r.Do("SET", "name", "张三")if err != nil {fmt.Println(err)return}// get 操作var reply interface{}reply, err = r.Do("GET", "name")if err != nil {fmt.Println(err)return}fmt.Println(string(reply.([]byte)))
}
05 通过String自动转换字符串
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()// set 操作_, err = r.Do("SET", "name", "张三")if err != nil {fmt.Println(err)return}// get 操作var reply stringreply, err = redis.String(r.Do("GET", "name"))if err != nil {fmt.Println(err)return}fmt.Println(reply)
}
06 通过Do实现mset和mget的操作
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()// set 操作// 也一定要注意,是:key1,value1,key2,value2... 的格式_, err = r.Do("MSET", "name", "张三", "age", 22, "gender", "男")if err != nil {fmt.Println(err)return}// get 操作// 这个传递的是想要哪些keyvar reply []stringreply, err = redis.Strings(r.Do("MGET", "name", "age", "gender"))if err != nil {fmt.Println(err)return}fmt.Println(reply)
}
07 通过Do实现hset和hget的操作
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()_, err = r.Do("HSET", "user", "name", "张三")if err != nil {fmt.Println(err)return}var reply stringreply, err = redis.String(r.Do("HGET", "user", "name"))if err != nil {fmt.Println(err)return}fmt.Println(reply)
}
08 通过Do实现lpush和lpop以及llen的操作
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (r redis.Connerr error
)func InitRedis() {r, err = redis.Dial("tcp", "127.0.0.1:6379")if err != nil {fmt.Println(err)return}
}func CloseRedis() {r.Close()
}func main() {InitRedis()defer CloseRedis()_, err = r.Do("LPUSH", "arr", "张三", "李四", "王五")if err != nil {fmt.Println(err)return}var reply stringreply, err = redis.String(r.Do("LPOP", "arr"))if err != nil {fmt.Println(err)return}fmt.Println(reply)var length intlength, err = redis.Int(r.Do("LLEN", "arr"))if err != nil {fmt.Println(err)return}fmt.Println(length)}
09 Redis的连接池介绍
10 Redis连接池的创建和使用
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (pool *redis.Poolerr error
)func InitRedis() {pool = &redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (redis.Conn, error) {return redis.Dial("tcp", "127.0.0.1:6379")},}
}func main() {InitRedis()r := pool.Get()defer r.Close()_, err = r.Do("LPUSH", "arr", "张三", "李四", "王五")if err != nil {fmt.Println(err)return}var reply stringreply, err = redis.String(r.Do("LPOP", "arr"))if err != nil {fmt.Println(err)return}fmt.Println(reply)var length intlength, err = redis.Int(r.Do("LLEN", "arr"))if err != nil {fmt.Println(err)return}fmt.Println(length)}
11 Redis的管道操作
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (pool *redis.Poolerr error
)func InitRedis() {pool = &redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (redis.Conn, error) {return redis.Dial("tcp", "127.0.0.1:6379")},}
}func main() {InitRedis()r := pool.Get()defer r.Close()// 写入缓冲r.Send("SET", "name1", "张三")r.Send("SET", "name2", "李四")// 清空缓冲,写入服务端(Redis)r.Flush()// 读取:先进先出receive, err := r.Receive()fmt.Printf("receive:%#v, err:%v\n", receive, err)receive, err = r.Receive()fmt.Printf("receive:%#v, err:%v\n", receive, err)// 因为没有数据了,所以会一直处于等待状态receive, err = r.Receive()fmt.Printf("receive:%#v, err:%v\n", receive, err)
}
12 Redis的事务操作
package mainimport ("fmt""github.com/gomodule/redigo/redis"
)var (pool *redis.Poolerr error
)func InitRedis() {pool = &redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (redis.Conn, error) {return redis.Dial("tcp", "127.0.0.1:6379")},}
}func main() {InitRedis()r := pool.Get()defer r.Close()r.Send("MULTI") // 开启事务// 事务过程中的一些业务操作r.Send("INCR", "num1")r.Send("INCR", "num2")reply, err := r.Do("EXEC") // 执行事务fmt.Printf("%#v err:%v\n", reply, err)
}
13 实现redigo的本地化
14 对zdpgo_redis的包结构进行调整
15 发布zdpgo_redisv1.1.0版本
16 新增用户
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_redis"
)var (pool *zdpgo_redis.Poolerr error
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}func main() {InitRedis()r := pool.Get()defer r.Close()// string hash list// string hash users:{1:{id:1,xxx},2:xxx}// string 代码会更简单zs := User{2, "李四", 23}key := fmt.Sprintf("user/%d", zs.Id)zsBytes, _ := json.Marshal(zs)value := string(zsBytes)r.Do("SET", key, value)value2, _ := zdpgo_redis.String(r.Do("GET", key))fmt.Println(value2)
}
17 修改用户
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_redis"
)var (pool *zdpgo_redis.Poolerr error
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}func main() {InitRedis()r := pool.Get()defer r.Close()id := 1name := "李四"// 查询key := fmt.Sprintf("user/%d", id)value2, _ := zdpgo_redis.String(r.Do("GET", key))fmt.Println(value2)// 解析var user Userjson.Unmarshal([]byte(value2), &user)fmt.Println(user)// 修改user.Name = name// 重新存储jsonBytes, _ := json.Marshal(user)fmt.Println(string(jsonBytes))r.Do("SET", key, string(jsonBytes))
}
18 删除用户
package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_redis"
)var (pool *zdpgo_redis.Poolerr error
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}func main() {InitRedis()r := pool.Get()defer r.Close()id := 1// 查询key := fmt.Sprintf("user/%d", id)value2, _ := zdpgo_redis.String(r.Do("GET", key))fmt.Println(value2)// 删除r.Do("DEL", key)// 再查询value2, _ = zdpgo_redis.String(r.Do("GET", key))fmt.Println(value2)
}
19 查询所有用户
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_redis"
)var (pool *zdpgo_redis.Poolerr error
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}func main() {InitRedis()r := pool.Get()defer r.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(r.Do("KEYS", "user/*"))fmt.Println(userKeys)// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(r.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}fmt.Println(users)
}
20 实现查询所有用户的接口并进行测试
package mainimport ("encoding/json""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.GET("/user", RouterGetUser)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""io""net/http"
)func main() {resp, err := http.Get("http://localhost:8888/user")if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
21 实现新增用户的接口并进行测试
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Userzdpgo_httprouter.GetJson(r, &user)id := time.Now().Nanosecond()user.Id = id// 新增key := fmt.Sprintf("user/%d", user.Id)zsBytes, _ := json.Marshal(user)value := string(zsBytes)rdb.Do("SET", key, value)// 返回zdpgo_httprouter.ResponseSuccess(w, user)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.POST("/user", RouterAddUser)router.GET("/user", RouterGetUser)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_httprouter""io"
)func main() {targetUrl := "http://localhost:8888/user"data := map[string]interface{}{"name": "王五","age": 35,}resp, err := zdpgo_httprouter.SendJson("POST", targetUrl, data)if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
22 解决ID唯一性的问题
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int64 `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Userzdpgo_httprouter.GetJson(r, &user)id := time.Now().UnixNano()user.Id = id// 新增key := fmt.Sprintf("user/%d", user.Id)zsBytes, _ := json.Marshal(user)value := string(zsBytes)rdb.Do("SET", key, value)// 返回zdpgo_httprouter.ResponseSuccess(w, user)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.POST("/user", RouterAddUser)router.GET("/user", RouterGetUser)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_httprouter""io"
)func main() {targetUrl := "http://localhost:8888/user"data := map[string]interface{}{"name": "王五","age": 35,}resp, err := zdpgo_httprouter.SendJson("POST", targetUrl, data)if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
23 实现修改用户的接口并进行测试
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int64 `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Userzdpgo_httprouter.GetJson(r, &user)id := time.Now().UnixNano()user.Id = id// 新增key := fmt.Sprintf("user/%d", user.Id)zsBytes, _ := json.Marshal(user)value := string(zsBytes)rdb.Do("SET", key, value)// 返回zdpgo_httprouter.ResponseSuccess(w, user)
}func RouterUpdateUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Uservar idStr = ps.ByName("id")zdpgo_httprouter.GetJson(r, &user)// 查询key := fmt.Sprintf("user/%s", idStr)userJson, _ := zdpgo_redis.String(rdb.Do("GET", key))// 解析var dbUser Userjson.Unmarshal([]byte(userJson), &dbUser)// 修改dbUser.Name = user.NamedbUser.Age = user.Age// 重新存储jsonBytes, _ := json.Marshal(dbUser)rdb.Do("SET", key, string(jsonBytes))// 返回zdpgo_httprouter.ResponseSuccess(w, dbUser)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.POST("/user", RouterAddUser)router.GET("/user", RouterGetUser)router.PUT("/user/:id", RouterUpdateUser)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_httprouter""io"
)func main() {targetUrl := "http://localhost:8888/user/108534300"data := map[string]interface{}{"name": "王六","age": 35,}resp, err := zdpgo_httprouter.SendJson("PUT", targetUrl, data)if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
24 实现删除用户的接口并进行测试
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int64 `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Userzdpgo_httprouter.GetJson(r, &user)id := time.Now().UnixNano()user.Id = id// 新增key := fmt.Sprintf("user/%d", user.Id)zsBytes, _ := json.Marshal(user)value := string(zsBytes)rdb.Do("SET", key, value)// 返回zdpgo_httprouter.ResponseSuccess(w, user)
}func RouterUpdateUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Uservar idStr = ps.ByName("id")zdpgo_httprouter.GetJson(r, &user)// 查询key := fmt.Sprintf("user/%s", idStr)userJson, _ := zdpgo_redis.String(rdb.Do("GET", key))// 解析var dbUser Userjson.Unmarshal([]byte(userJson), &dbUser)// 修改dbUser.Name = user.NamedbUser.Age = user.Age// 重新存储jsonBytes, _ := json.Marshal(dbUser)rdb.Do("SET", key, string(jsonBytes))// 返回zdpgo_httprouter.ResponseSuccess(w, dbUser)
}func RouterDeleteUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var idStr = ps.ByName("id")// 查询key := fmt.Sprintf("user/%s", idStr)rdb.Do("DEL", key)// 返回zdpgo_httprouter.ResponseSuccess(w, nil)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.POST("/user", RouterAddUser)router.GET("/user", RouterGetUser)router.PUT("/user/:id", RouterUpdateUser)router.DELETE("/user/:id", RouterDeleteUser)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_httprouter""io"
)func main() {targetUrl := "http://localhost:8888/user/53"data := map[string]interface{}{}resp, err := zdpgo_httprouter.SendJson("DELETE", targetUrl, data)if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
25 实现根据ID查询用户的接口并进行测试
package mainimport ("encoding/json""fmt""github.com/zhangdapeng520/zdpgo_httprouter""github.com/zhangdapeng520/zdpgo_redis""net/http""time"
)type User struct {Id int64 `json:"id"`Name string `json:"name"`Age int `json:"age"`
}var (pool *zdpgo_redis.Pool
)func InitRedis() {pool = &zdpgo_redis.Pool{MaxIdle: 16,MaxActive: 1024,IdleTimeout: 300,Dial: func() (zdpgo_redis.Conn, error) {return zdpgo_redis.Dial("tcp", "127.0.0.1:6379")},}
}func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()// 获取所有的keyuserKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))// 查询var users []Userfor _, key := range userKeys {var user UseruserStr, _ := zdpgo_redis.String(rdb.Do("GET", key))json.Unmarshal([]byte(userStr), &user)users = append(users, user)}zdpgo_httprouter.ResponseSuccess(w, users)
}func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Userzdpgo_httprouter.GetJson(r, &user)id := time.Now().UnixNano()user.Id = id// 新增key := fmt.Sprintf("user/%d", user.Id)zsBytes, _ := json.Marshal(user)value := string(zsBytes)rdb.Do("SET", key, value)// 返回zdpgo_httprouter.ResponseSuccess(w, user)
}func RouterUpdateUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var user Uservar idStr = ps.ByName("id")zdpgo_httprouter.GetJson(r, &user)// 查询key := fmt.Sprintf("user/%s", idStr)userJson, _ := zdpgo_redis.String(rdb.Do("GET", key))// 解析var dbUser Userjson.Unmarshal([]byte(userJson), &dbUser)// 修改dbUser.Name = user.NamedbUser.Age = user.Age// 重新存储jsonBytes, _ := json.Marshal(dbUser)rdb.Do("SET", key, string(jsonBytes))// 返回zdpgo_httprouter.ResponseSuccess(w, dbUser)
}func RouterDeleteUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var idStr = ps.ByName("id")// 查询key := fmt.Sprintf("user/%s", idStr)rdb.Do("DEL", key)// 返回zdpgo_httprouter.ResponseSuccess(w, nil)
}func RouterGetUserId(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {rdb := pool.Get()defer rdb.Close()var idStr = ps.ByName("id")// 查询key := fmt.Sprintf("user/%s", idStr)userJson, _ := zdpgo_redis.String(rdb.Do("GET", key))var dbUser Userjson.Unmarshal([]byte(userJson), &dbUser)// 返回zdpgo_httprouter.ResponseSuccess(w, dbUser)
}func main() {InitRedis()router := zdpgo_httprouter.New()router.POST("/user", RouterAddUser)router.GET("/user", RouterGetUser)router.PUT("/user/:id", RouterUpdateUser)router.DELETE("/user/:id", RouterDeleteUser)router.GET("/user/:id", RouterGetUserId)server := &http.Server{Addr: "0.0.0.0:8888",Handler: router,ReadTimeout: 5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}
package mainimport ("fmt""io""net/http"
)func main() {resp, err := http.Get("http://localhost:8888/user/1")if err != nil {fmt.Println(err)return}body := resp.BodybodyBytes, err := io.ReadAll(body)if err != nil {fmt.Println(err)return}fmt.Println(string(bodyBytes))
}
总结
本套教程主要讲解Go语言操作Redis基础知识,然后还讲解了管道,连接池,事务等高级用户。借助用户管理这个业务为中心,详细讲解了如何使用Go语言加Redis实现用户的增删改查操作,之后有结合httprouter的用法,开发用户管理的增删改查API接口。
通过本套课程,能帮你入门Go语言操作Redis的技术。
如果您需要完整的源码,打赏20元即可。
人生苦短,我用Python,我是您身边的Python私教~
相关文章:
Go+Redis零基础到用户管理系统API实战_20240730 课程笔记
概述 如果您没有Golang的基础,应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227 基础不好的同学每节课的代码最好配合视频进…...
ScreenAgent:基于LVLM的计算机控制智能体
ScreenAgent : A Vision Language Model-driven Computer Control Agent 论文链接: https://arxiv.org/abs/2402.07945https://arxiv.org/abs/2402.07945IJCAI 2024 1.概述 大型语言模型(LLM),诸如ChatGPT与GPT-4,在自然语言处理领域(涵盖生成、理解及对话等任务)展现出…...
谷粒商城实战笔记-129-商城业务-商品上架-nested数据类型场景
文章目录 扁平化处理扁平化处理导致的检索问题 解决方案:使用 nested 结构 在es的数据类型中有一个nested类型,本讲将重点讨论这个类型。 扁平化处理 PUT my_index/doc/1 {"group" : "fans","user" : [{"first&quo…...
axios请求响应拦截器
目录 axios-拦截器 拦截器的作用 请求拦截器-基本写法: axios请求拦截器-统一设置token 需求: 核心步骤: 关键代码: 响应拦截器-基本写法: axios响应拦截器-统一处理token失效 需求: 核心步骤: 关键代码: axios响应拦截器-数据剥离 需求: 核心步骤: 关键代码: ax…...
Python 中单例模式实现的几种方式
在设计模式中,单例模式是经常被提及和使用的一种模式。它保证一个类只有一个实例,并提供全局访问点。在Python中,有多种实现单例模式的方法。那么,如何选择合适的方法来实现单例模式呢? 单例模式在Python中的几种实现方…...
mysql数据库触发器同步数据
首先检查数据源库是否支持触发器,show ENGINES,如果FEDERATED是NO,表示未开启,如需开启,再mysql配置文件中,添加federated配置到mysqld下面。 一、同服务器不同库触发器同步,这里只举例插入数据…...
Prometheus-v2.45.0+Grafana+邮件告警
目录 普罗米修斯监控架构介绍 Prometheus 监控架构 1. 数据抓取(Scraping) 2. 时序数据库(TSDB) 3. 数据模型 4. PromQL 查询语言 5. 告警(Alerting) 6. Alertmanager 7. 可视化(Visu…...
LeetCode——572. 另一颗树的子树
通过万岁!!! 题目:给你两棵树,然后问subRoot是不是root的子树。也就是root某个节点的所有孩子节点在值和结构上完全与subRoot相同。思路:我的思路比较简单,就是遍历root,遇到root中…...
Spring Boot整合MyBatis-Flex
说明:MyBatis-Flex(官网地址:https://mybatis-flex.com/),是一款数据访问层框架,可实现项目中对数据库的访问,类比MyBatis-Plus。本文介绍,在Spring Boot项目整合MyBatis-Flex。 创…...
重塑未来体验:边缘计算与云原生的完美邂逅
🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、云原生的兴起 2、边缘计算的兴起 二、边缘计算基础 …...
浅谈基础数论(c++)
目录 一些常见的符号表示阶乘定理 快速幂模板题代码扩展:矩阵快速幂主要作用 欧拉函数扩展积性函数 欧拉函数求法筛选法求欧拉函数(积性函数) 扩展欧几里得裴蜀定理问题分析代码 问题分析 同余与逆元如何求解逆元扩展欧几里得 例题讲解X-Magi…...
jdk 17新特性 sealed 关键字
通俗理解 sealed 关键字就是给对象继承加了权限控制一样,你必须在我的规则范围内才可以继承我的类 使用 permits 关键字控制允许哪些子类继承 子类必须加以下三个关键字: final 最终继承类(继承到这个类就不允许再往下继承了)n…...
在仪器计量校准中,无尘车间洁净室检测有哪些方法和流程?
仪器计量校准行业内,无尘车间洁净室检测可以说是较为热门的业务,因为其预算高,且检测流程不是太繁琐,很多仪器计量校准机构也是设立相关实验室,专门处理相关仪器的检测。不过虽然许多机构想要涉足该领域,但…...
【跨时代】第四次工业革命彻底来袭!什么是AI+
你有没有一种很割裂的感觉,就是在短视频里,AI已经要改变全世界了 但自己一用,却发现只能和AI聊聊天 画几张图 难道是姿势不对?但具体是哪里不对呢。 作为一个老牌程序员,我前面分享了很多计算机相关内容,总…...
前端性能优化-纲领篇
前端性能优化 本模块将梳理前端性能优化的相关知识点 从浏览器输入 URL 到页面展示发生了什么 完整版请查看[Browser_网络_安全]的部分,这里只是简单的梳理一下 DNS 解析TCP 连接浏览器发出 HTTP 请求服务器处理请求并返回 HTTP 报文浏览器解析渲染页面 性能优…...
深度学习-----------数值稳定性
目录 神经网络的梯度数值稳定性的常见两个问题例子:MLP 梯度爆炸梯度爆炸的问题 梯度消失梯度消失的问题 总结模型初始化和激活函数让训练更加稳定让每层的方差是一个常数 权重初始化正向均值和方差正向均值正向方差 反向均值和方差Xavier初始正向和反向的均值和方差…...
SpringBoot项目接口可以承受的调用次数
一个Spring Boot接口能够承受的调用次数主要取决于几个因素,包括但不限于: 服务器硬件:CPU、内存、硬盘I/O速度以及网络带宽都会直接影响接口的处理能力和并发量。操作系统和JVM配置:操作系统调度策略、JVM的内存分配、垃圾回收机…...
抽象代数精解【8】
文章目录 希尔密码矩阵矩阵基本概念行列式基本概念特殊矩阵关于乘法运算构成群 加解密原理密钥加密函数解密函数 Z 26 上的运算( Z 256 与此类似) Z_{26}上的运算(Z_{256}与此类似) Z26上的运算(Z256与此类似&…...
数据结构与算法 - 二叉树
1. 概述 二叉树是这么一种树状结构:每个节点最多有两个孩子,左孩子和右孩子 完全二叉树:是一种二叉树结构,除了最后一层以外,每一层都必须填满,填充时要遵循从左到右 平衡二叉树:是一种二叉树…...
Spring Cloud Gateway如何给一个请求加请求头
在Spring Cloud Gateway中,可以通过编写一个GlobalFilter来给所有请求加请求头,或者通过编写一个SpecificFilter来给特定路径的请求加请求头。 全局过滤器(GlobalFilter)的实现方式如下: Configuration public class…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
