Go使用Gin+Redis实现增删改查
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go使用Gin+Redis实现增删改查相关的知识,希望对你有一定的参考价值。
Go使用Gin+Redis实现增删改查
0.前置知识
-
Go中的struct。
-
Redis、Gin框架。
-
Web基础。
1.架构
使用Redis作为数据库,Gin作为Web框架。
2.功能模块
1.自定义Person结构体
2.实现对Person的增删改查。
- 根据id查询或查询所有
- 插入
- 修改
- 删除
3.实现流程
1.建立Redis数据库。
2.编写Web接口(增删改查)
3.通过postman测试或者直接网页请求测试。
4.代码
package main
// 导入模块
import (
"bytes"
"context"
"database/sql"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"log"
"net/http"
"strconv"
)
var db *sql.DB
var cnt int
// Person 自定义Person类
type Person struct
Id int `json:"id"`
FirstName string `json:"first_name" form:"first_name"`
LastName string `json:"last_name" form:"last_name"`
func (g *Person) MarshalBinary() (data []byte, err error)
return json.Marshal(g)
func (g *Person) UnmarshalBinary(data []byte) (err error)
return json.Unmarshal(data, g)
func (p *Person) get(c *redis.Client, ctx *context.Context) (person Person, err error)
err = c.Get(*ctx, strconv.Itoa(p.Id)).Scan(p)
if err != nil
log.Fatalln("get fail!")
return
person = *p
return
func (p *Person) getAll(c *redis.Client, ctx *context.Context) (persons []Person, err error)
var ids []string
ids, err = c.Keys(*ctx, "[1-9]*").Result()
for _, id := range ids
myid, _ := strconv.Atoi(id)
var person = Person
Id: myid,
person, _ = person.get(c, ctx)
persons = append(persons, person)
return
func (p *Person) add(c *redis.Client, ctx *context.Context) (Id int, err error)
// HMSet 批量设置 map[string]interface"age": 18, "sex": "male"
cnt += 1
Id = cnt
p.Id = Id
_, err = c.Set(*ctx, strconv.Itoa(cnt), p, 0).Result()
if err != nil
return
return
func (p *Person) update(c *redis.Client, ctx *context.Context) (rows int, err error)
if c.Exists(*ctx, strconv.Itoa(p.Id)).Val() == 1
_, err = c.Set(*ctx, strconv.Itoa(p.Id), p, 0).Result()
if err != nil
return
rows = 1
return
func (p *Person) del(c *redis.Client, ctx *context.Context) (rows int, err error)
if c.Exists(*ctx, strconv.Itoa(p.Id)).Val() == 1
var my int64
my, err = c.Del(*ctx, strconv.Itoa(p.Id)).Result()
rows = int(my)
if err != nil
return
return
func test(db *sql.DB)
rows, err := db.Query("select * from person")
if err != nil
return
defer rows.Close()
var persons []Person
for rows.Next()
var person Person
rows.Scan(&person.Id, &person.FirstName, &person.LastName)
persons = append(persons, person)
fmt.Println(persons)
func main()
ctx := context.Background()
rdb := redis.NewClient(&redis.Options
Addr: "localhost:6379",
Password: "",
DB: 0,
)
rdb.FlushDB(ctx)
defer rdb.Close()
_, err := rdb.Ping(ctx).Result() // PING, <nil>
if err != nil
fmt.Println("connect redis failed:", err)
return
//创建路由引擎
router := gin.Default()
//查询,返回所有对象和对象个数
router.GET("/persons", func(context *gin.Context)
p := Person
persons, err := p.getAll(rdb, &ctx)
if err != nil
log.Fatalln(err)
context.JSON(http.StatusOK, gin.H
"result": persons,
"count": len(persons),
)
)
//根据id查询
router.GET("/person/:id", func(context *gin.Context)
var result gin.H
id := context.Param("id")
Id, err := strconv.Atoi(id)
if err != nil
log.Fatalln(err)
p := Person
Id: Id,
person, err := p.get(rdb, &ctx)
if err != nil
result = gin.H
"result": nil,
"count": 0,
else
result = gin.H
"result": person,
"count": 1,
context.JSON(http.StatusOK, result)
)
//创建person
router.POST("/person", func(context *gin.Context)
var p Person
err := context.Bind(&p)
if err != nil
log.Fatalln(err)
Id, err := p.add(rdb, &ctx)
if err != nil
log.Fatalln(err)
fmt.Println(Id)
name := p.FirstName + " " + p.LastName
context.JSON(http.StatusOK, gin.H
"message": fmt.Sprintf(" %s 成功创建", name),
)
)
//更新update
router.PUT("/person/:id", func(context *gin.Context)
var (
p Person
buffer bytes.Buffer
)
id := context.Param("id")
Id, err := strconv.Atoi(id)
if err != nil
log.Fatalln(err)
err = context.Bind(&p)
if err != nil
log.Fatalln(err)
p.Id = Id
rows, err := p.update(rdb, &ctx)
if err != nil
log.Fatalln(err)
fmt.Println(rows)
buffer.WriteString(p.FirstName)
buffer.WriteString(" ")
buffer.WriteString(p.LastName)
name := buffer.String()
context.JSON(http.StatusOK, gin.H
"message": fmt.Sprintf("成功更新到%s", name),
)
)
//删除person
router.DELETE("/person/:id", func(context *gin.Context)
id := context.Param("id")
Id, err := strconv.ParseInt(id, 10, 10)
if err != nil
log.Fatalln(err)
p := PersonId: int(Id)
rows, err := p.del(rdb, &ctx)
if err != nil
log.Fatalln(err)
fmt.Println("delete rows: ", rows)
context.JSON(http.StatusOK, gin.H
"message": fmt.Sprintf("成功删除用户:%s", id),
)
)
router.Run(":8080")
5.结果
6.总结
6.1 对于复杂类型如struct,存储时需要进行序列化和反序列化。
具体来说就是重载序列化和反序列化这两个函数。
func (g *Person) MarshalBinary() (data []byte, err error)
return json.Marshal(g)
func (g *Person) UnmarshalBinary(data []byte) (err error)
return json.Unmarshal(data, g)
不然会出现下面的报错
can’t marshal *main.Person (implement encoding.BinaryMarshaler)
6.2 因为Redis的key都是string类型,所以需要用到int和string类型的转换。
可以使用strconv包的Itoa和Atoi
str = strconv.Itoa(p.Id) //int -> string
p.Id = strconv.Atoi(str) //string -> int
6.3 因为Redis的Set 不存在就插入,存在就覆盖。
所以Set函数可以实现插入和更新两个操作。
6.4 Redis进行keys的模糊查询时,只有*,[],?
这三种。
不能使用\\d
这种,所以怎么样实现正整数的匹配,有待商榷qwq。
以上是关于Go使用Gin+Redis实现增删改查的主要内容,如果未能解决你的问题,请参考以下文章