gin学习

gin学习

安装gin

  1. 需要先安装go
  2. 再安装gin,在终端输入go get -u -v github.com/gin-gonic/gin(本人使用的是mac电脑,以下都是mac操作)
  3. 我遇到的一些安装问题
    下载超时,直接修改go配置即可
    第一步 go env -w GO111MODULE=on
    第二步 go env -w GOPROXY=https://goproxy.cn,direct
    修改完后可输入go env进行查看是否修改成功,修改成功再进行
    go get -u -v github.com/gin-gonic/gin 即可

使用gin启动一个web服务

直接用代码显示每句代码什么意思都用注释写明

package main
// 引入gin
import "github.com/gin-gonic/gin"
// main函数
func main() {
	// 创建一个默认路由引擎
	r := gin.Default()

	// 配置路由
	r.GET("/", func(context *gin.Context) {
		context.String(200, "值:%v", "你好")
	})

	// 启动一个web服务
	r.Run() // 可以写入想要的端口号,r.Run(":8888")
}

如果跑了代码,每次修改都需要重新跑一次

热加载

gin官方并没有提供热加载的功能,就需要借助第三方工具
本人使用的是fresh,也有其他的热加载工具
安装方法(在终端直接输入即可):

go get github.com/pilu/fresh

使用方法直接在终端输入fresh即可

GET请求传值

Query()可以获取到传过来的值
DefaultQuery()可以获取到传过来的值,如果没值可以输入默认值

// 如何获取get传值
	r.GET("/get", func(context *gin.Context) {
		// 无默认值
		username := context.Query("username")
		age := context.Query("age")
		
		// 如果没有传值,有默认值
		page := context.DefaultQuery("page", "1")

		context.JSON(http.StatusOK, gin.H{
			"username": username,
			"age":      age,
			"page":     page,
		})
	})

在浏览器输入http://localhost:8080/get?username=你好&age=18&page=10
就可以得到{“age”:“18”,“page”:“10”,“username”:“你好”}
如果不传page也可以有默认值http://localhost:8080/get?username=你好&age=18
得到{“age”:“18”,“page”:“1”,“username”:“你好”}

POST请求传值(form)

// 如何过去post传值from
	r.POST("/post", func(context *gin.Context) {
		// 无默认值
		username := context.PostForm("username")
		password := context.PostForm("password")
		// 有默认值
		age := context.DefaultPostForm("age", "18")
		context.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
			"age":      age,
		})
	})

可以用前端form标签试试,也可以使用Gin的html模版语法,我直接使用apifox在这里插入图片描述

GET和POST结构体请求

两个差别不大,下面我放一个post请求的图片

type UserInfo struct {
	Username string `json:"username" form:"username"`
	Password string `json:"password" form:"password"`
}
func main() {
	// 创建一个默认路由引擎
	r := gin.Default()
	
	// GET结构体请求
	r.GET("/getUser", func(context *gin.Context) {
		user := &UserInfo{}
		err := context.ShouldBind(&user)
		if err == nil {
			context.JSON(http.StatusOK, user)
		} else {
			context.JSON(http.StatusBadRequest, gin.H{
				"err": err.Error(),
			})
		}
	})
	
	// POST结构体请求
	r.POST("/postUser", func(context *gin.Context) {
		user := &UserInfo{}
		err := context.ShouldBind(&user)
		if err == nil {
			context.JSON(http.StatusOK, user)
		} else {
			context.JSON(http.StatusBadRequest, gin.H{
				"err": err.Error(),
			})
		}
	})
	// 启动一个web服务
	r.Run()
}

在这里插入图片描述

GET动态路由

	// GET动态路由
	r.GET("/list/:cid", func(context *gin.Context) {
		cid := context.Param("cid")
		context.String(http.StatusOK, "%v", cid)
	})

在这里插入图片描述

路由组

官方文档路由组
官方直接写在main函数中,我的例子就抽离出来

  1. 创建一个文件夹routers
  2. 在routers中创建一个go文件,api.go
// 传入创建的路由引擎,传入的类型到main看
func Api(r *gin.Engine) {
	r.GET("/api/userList", func(context *gin.Context) {
		context.String(http.StatusOK, "这是用户列表接口")
	})
}
  1. 在main函数中使用
// 记得要引入对应的文件
import (
	"day1/routers"
)
// 在main函数的创建路由引擎后面调用Api函数
routers.Api(r)

中间件

  1. 路由中间件
    在路由中间件函数中Next之前的代码为请求前处理,在Next之后的代码为请求后处理
// 路由中间件函数
func routeMiddleware(c *gin.Context) {
	fmt.Println("我是路由中间件")

	// 去执行请求剩余处理程序
	c.Next()

	fmt.Println("我是路由中间件2")
}

func main() {
	r := gin.Default()
	
	r.GET("/", routeMiddleware, func(context *gin.Context) {
		fmt.Println("我是首页")
		context.String(http.StatusOK, "值:%v", "你好")
	})
}

这是打印出来的顺序
在这里插入图片描述
2. 全局中间件
和路由中间件其实是差不多的,只要在main函数中加入Use(),就可以在任何请求的情况下都会使用到全局中间件

// 全局中间件
func middleware(c *gin.Context) {
	fmt.Println("我是全局中间件")

	// 去执行请求剩余处理程序
	c.Next()

	fmt.Println("我是全局中间件2")
}

func main() {
	r := gin.Default()
	r.Use(middleware)
	
	r.GET("/", func(context *gin.Context) {
		fmt.Println("我是首页")
		context.String(http.StatusOK, "值:%v", "你好")
	})
}
// 就会打印出	我是全局中间件	我是首页	我是全局中间件2

任何请求都可以有多个中间件(路由、全局) 也可以将中间件函数单独拿出来,创建一个文件夹(middlewares),在文件夹创建一个go文件,里面上中间件的函数,在需要的地方引入就可以了具体可以看文档

  1. 控制器和中间件传值
    将中间件单独提出来
package middlewares

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

func InitMiddleware(c *gin.Context) {
	// 获取时间
	fmt.Println(time.Now())
	// 获取请求地址
	fmt.Println(c.Request.URL)
	// 传值
	c.Set("username", "我有多么帅")
}

将中间件引入对应的路由中

package routers

import (
	"day1/controllers/admin"
	"day1/middlewares"
	"github.com/gin-gonic/gin"
)

// Api 传入创建的路由引擎,传入的类型到main看
func Api(r *gin.Engine) {
	apiRouters := r.Group("/api", middlewares.InitMiddleware)
	{
		apiRouters.GET("/userList", admin.UserControllers{}.Index)
	}
}
// 记得到main函数中引入routers.Api(r)

路由中使用了控制器,就可以在控制器中使用中间件传过来的值

package admin

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

type UserControllers struct {
}

func (con UserControllers) Index(c *gin.Context) {
	// 获取中间件传来的值
	username, _ := c.Get("username")
	// 类型断言
	v, ok := username.(string)
	if ok {
		c.String(http.StatusOK, "用户列表 " + v)
	} else {
		c.String(http.StatusOK, "用户列表 失败")
	}
}

  1. 中间件注意事项
    如果你是用Default创建的路由引擎,它是会自带两个中间件的,如果你使用New创建的路由引擎就不会有默认的中间件
    Default自带的中间件分别是Logger和Recovery
    Logger中间件将日志写入gin.DefaultWriter
    Recouery中间件会recover任何panic,如果有panic的话就会写入500响应码

文件上传

直接续中间件下面写的

func (con UserControllers) Upload(c *gin.Context) {
	// 获取文件
	file, err := c.FormFile("file")

	// 获取文件保存路径   file.Filename获取文件名称
	dst := path.Join("./static/upload", file.Filename)

	// 判断是否获取成功
	if err == nil {
		// 获取文件保存路径   file.Filename获取文件名称
		dst := path.Join("./static/upload", file.Filename)
		// 将图片存到对应的目录中
		c.SaveUploadedFile(file, dst)
	}

	c.JSON(http.StatusOK, gin.H{
		"dst": dst,
	})
}

单文件和多文件是一样的,获取多个文件即可。多文件上传还分相同名字上传以数组的形式循环遍历获取,不同名字上传直接对不同名字进行处理。

数据库连接

我这里使用的数据库是mysql,用了gorm工具,使用这个工具就可以不需要写sql语句了

  1. 安装对应的依赖库go get -u gorm.io/gormgo get -u gorm.io/driver/mysql,后面这个命令如果你是别的数据库可以修改,比如go get -u gorm.io/driver/sqlite
  2. 当然你还需要准备mysql,启动mysql,mysql -u root -p,输入密码即可
  3. 连接数据库
import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 结构体和数据库表字段一致,首字母大写
type User struct {
	Id   int
	Name string
	Age  int
}
func main() {
	// 连接数据库需要准备的东西
	// root是数据库账号,xxxxx是数据库密码,item是连接对应的库
	dsn := "root:xxxxxx@tcp(127.0.0.1:3306)/item?charset=utf8mb4"
	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 对连接失败进行判断
	if err != nil {
		fmt.Println(err)
	}

	// 添加一条数据
	user := &User{Id: 1, Name: "张三", Age: 2}
	db.Create(&user)}

	// 查找一条数据
	userList := &User{}
	db.Where("id=1").First(&userList)
} 

持续更新中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值