Go+Redis零基础到用户管理系统API实战_20240730 课程笔记

news2025/1/11 2:28:21

概述

如果您没有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 edis的连接池介绍
  • 10 edis连接池的创建和使用
  • 11 edis的管道操作
  • 12 edis的事务操作
  • 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 main

import (
	"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 main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 string
	reply, err = redis.String(r.Do("GET", "name"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(reply)
}

06 通过Do实现mset和mget的操作

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 操作
	// 这个传递的是想要哪些key
	var reply []string
	reply, err = redis.Strings(r.Do("MGET", "name", "age", "gender"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(reply)
}

07 通过Do实现hset和hget的操作

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 string
	reply, err = redis.String(r.Do("HGET", "user", "name"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(reply)
}

08 通过Do实现lpush和lpop以及llen的操作

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	r   redis.Conn
	err 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 string
	reply, err = redis.String(r.Do("LPOP", "arr"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(reply)

	var length int
	length, err = redis.Int(r.Do("LLEN", "arr"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(length)

}

09 Redis的连接池介绍

10 Redis连接池的创建和使用

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	pool *redis.Pool
	err  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 string
	reply, err = redis.String(r.Do("LPOP", "arr"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(reply)

	var length int
	length, err = redis.Int(r.Do("LLEN", "arr"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(length)

}

11 Redis的管道操作

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	pool *redis.Pool
	err  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 main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
)

var (
	pool *redis.Pool
	err  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 main

import (
	"encoding/json"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_redis"
)

var (
	pool *zdpgo_redis.Pool
	err  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 main

import (
	"encoding/json"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_redis"
)

var (
	pool *zdpgo_redis.Pool
	err  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
	name := "李四"

	// 查询
	key := fmt.Sprintf("user/%d", id)
	value2, _ := zdpgo_redis.String(r.Do("GET", key))
	fmt.Println(value2)

	// 解析
	var user User
	json.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 main

import (
	"fmt"
	"github.com/zhangdapeng520/zdpgo_redis"
)

var (
	pool *zdpgo_redis.Pool
	err  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 main

import (
	"encoding/json"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_redis"
)

var (
	pool *zdpgo_redis.Pool
	err  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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(r.Do("KEYS", "user/*"))
	fmt.Println(userKeys)

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := zdpgo_redis.String(r.Do("GET", key))
		json.Unmarshal([]byte(userStr), &user)
		users = append(users, user)
	}
	fmt.Println(users)
}

20 实现查询所有用户的接口并进行测试

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	resp, err := http.Get("http://localhost:8888/user")
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

21 实现新增用户的接口并进行测试

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 User
	zdpgo_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 main

import (
	"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.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

22 解决ID唯一性的问题

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 User
	zdpgo_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 main

import (
	"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.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

23 实现修改用户的接口并进行测试

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 User
	zdpgo_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 User
	var 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 User
	json.Unmarshal([]byte(userJson), &dbUser)

	// 修改
	dbUser.Name = user.Name
	dbUser.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 main

import (
	"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.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

24 实现删除用户的接口并进行测试

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 User
	zdpgo_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 User
	var 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 User
	json.Unmarshal([]byte(userJson), &dbUser)

	// 修改
	dbUser.Name = user.Name
	dbUser.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 main

import (
	"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.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

25 实现根据ID查询用户的接口并进行测试

package main

import (
	"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()

	// 获取所有的key
	userKeys, _ := zdpgo_redis.Strings(rdb.Do("KEYS", "user/*"))

	// 查询
	var users []User
	for _, key := range userKeys {
		var user User
		userStr, _ := 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 User
	zdpgo_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 User
	var 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 User
	json.Unmarshal([]byte(userJson), &dbUser)

	// 修改
	dbUser.Name = user.Name
	dbUser.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 User
	json.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 main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	resp, err := http.Get("http://localhost:8888/user/1")
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, 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私教~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959943.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Adaptive AUTOSAR中,默认有一个机器状态的功能组管理平台进程的生命周期,那怎么切换到其他功能组的状态呢?

在Adaptive AUTOSAR中,状态管理(State Management, SM)模块和执行管理(Execution Management, EM)模块共同负责功能组状态的切换。 以下是切换到其他功能组状态的步骤: 状态切换流程 状态请求: 状态管理模块接收到来自应用程序、功能集群、平台健康管理、诊断等的状态切…

代码随想录算法训练营第33天|62.不同路径、63. 不同路径 II、343. 整数拆分、96.不同的二叉搜索树

打卡Day33 1.62.不同路径2.63. 不同路径 II3.343. 整数拆分4.96.不同的二叉搜索树 1.62.不同路径 题目链接:62.不同路径 文档讲解: 代码随想录 动规五部曲: (1)确定dp数组和下标的含义 dp[ i ][ j ] 表示到达 i x j …

JNDI注入-高版本绕过

参考博客: JNDI注入与动态类加载 探索高版本 JDK 下 JNDI 漏洞的利用方法 - 跳跳糖 (tttang.com) 分析版本 jdk8u201 分析流程 修复 在ldap绕过中,我们讲了LDAP的修复,下面用jdk8u201具体来看下修复。 修复之前,利用是在L…

档案馆可视化管理系统

通过图扑可视化技术,实现档案馆内文件、资料的高效管理与实时监控,提升档案数据的查询、存档和维护效率。

【建议收藏】大数据Hadoop实战入门手册,配套B站视频教程1小时速通

大数据Hadoop入门实战专栏 大数据技术概述大数据简介Hadoop简介 大数据集群环境搭建环境搭建概述虚拟机准备集群搭建Java开发环境准备 分布式文件系统HDFS学习前期概述HDFS Shell命令HDFS可视化界面HDFS Java API编程环境初始化API基本使用创建目录更改目录权限上传文件查看目录…

docker pgsql实现pg_jieba全文检索

安装pg_jieba分词器 安装依赖工具 查看docker运行的所有容器 docker ps进入pg数据库容器 docker exec -it postgres4postgis bash安装必要的工具和依赖 apt-get install -y git build-essential cmake libpq-dev postgresql-server-dev-all安装pg_jieba分词 git clone ht…

Apache DolphinScheduler用户线上Meetup火热来袭!

Apache DolphinScheduler 社区 8 月用户交流会精彩继续!本次活动邀请到老牌农牧产品实业集团铁骑力士架构工程师,来分享Apache DolphinScheduler在现代农牧食品加工场景中的应用实践。此外,还将有社区活跃贡献者以Apache DolphinScheduler为例…

为什么AI会一本正经地胡说八道

泛泛地说,AI一本正经地胡说八道的原因可以归结为:AI的理解能力受到其训练数据和算法的限制,如果问题表达不清晰或者背景信息不足,AI可能会产生错误的推理或输出;AI语言模型本质上是基于统计学习和模式匹配的&#xff0…

基于新型电力系统的有序充电解决方案

安科瑞 耿敏花 摘要:近年来,新能源汽车的销量快速增长,相应的充电桩数量也急剧增加,这一现象可能会给电网和变压器造成负担,与此同时,新型电力系统下以光伏为主的分布式发电系统占比也在逐渐提高,新能源的不稳定性叠加充电需求的不确定性会给…

MySQL基础练习题13-指定日期的产品价格

题目:找出在 2019-08-16 时全部产品的价格,假设所有产品在修改前的价格都是 10 。 准备数据 分析数据 题目:找出在 2019-08-16 时全部产品的价格,假设所有产品在修改前的价格都是 10 。 准备数据 ## 创建库 create tadabase d…

矩阵管理系统真的好用吗

在这个短视频盛行的时代,每个人都可能是下一个网红。但是,当你的账号遍布各大平台,每个平台都要求你不断更新内容时,你可能会问:有没有一种工具,可以让这一切变得更简单?这就是矩阵管理系统出现…

项目中AOP相关问题

答:AOP是面向切面编程,可以通过定义方法拦截器和切入点,实现将一些逻辑相同的代码块抽取到同一个模块中,这个模块就是切面。代码可以只关注业务实现,不用关注那些通用逻辑。 答:切面,通用模块&…

模型部署优化综述

一、引言 模型部署优化是一个涵盖众多环节的宽泛领域,从模型训练完成到实际硬件部署,涉及多个层面的工作,且每个环节对技术的要求各异。其本质是通过减小模型大小、提高推理速度等手段,使模型能在各种硬件中成功部署并实时有效运行。 二、模型剪枝技术 (一)模型剪枝的…

Oracle基础-集合

集合:两个结果集的字段个数和字段类型必须相同,才能使用集合操作。 --UNION 并集 重复行会去重 (SELECT A,B FROM DUAL UNION SELECT C,D FROM DUAL) UNION (SELECT A,B FROM DUAL UNION SELECT E,F FROM DUAL ); --UNION ALL 全集 包含所有记录 不去重…

学校会拒绝孤独症孩子吗?揭秘专业教育机构的关怀之心

在当今社会,孤独症孩子的教育问题备受关注。许多家长心中都存在着一个担忧:学校会拒绝孤独症孩子吗? 事实上,大多数专业的教育机构都怀揣着一颗关怀之心,不会轻易拒绝这些特殊的孩子。 专业的教育机构深知,…

畅捷通如何远程访问?

随时随地能够远程访问和操作畅捷通已经成为许多职场人士的迫切需求。作为一名有着亲身经历的使用者,今天我就来和大家分享一下实现畅捷通远程访问的绝佳方法。 曾几何时,为了能在外出时也能使用畅捷通办公,我可谓是绞尽脑汁。尝试过多种传统方…

trino开启https

作者:振鹭 一、生成https证书 (所用到的openssl和keytool命令都是linux自带的) 配置https证书: (1)创建目录 [hdfshadoop01 hadoop]# mkdir -p /data/ssl/ [hdfshadoop01 hadoop]# cd /data/ssl/&…

【全志H616开发】Linux守护进程

文章目录 守护进程简介基本特点创建一个守护进程通常涉及以下步骤:进程查看指令: 守护进程开发代码示例: 开机自动启动 守护进程 简介 Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性…

C语言斜向钥匙迷宫

目录 开头程序的流程图程序的效果结尾 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们来看一下我用C语言编译的斜向钥匙迷宫和与之相关的一些东西。 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <Windows.h> void printmaze(co…

数据结构算法-排序(二)

插入排序 插入排序核心 假设数组中的一部数据已经排好序&#xff0c;要插入的数据和这些数据进行比较&#xff0c;直到找到合适的位置插入新数据。 插入排序步骤 插入排序主要有以下步骤构成&#xff1a; 假设有序&#xff0c;我们假设**a[0]**已经排好序待插入的数据为a[j]…