gin 总结 101

本文详细介绍了Gin框架的使用,包括初始化引擎、数据绑定(query、路径、postform、json)、数据验证、文件上传、数据返回格式、路由组、中间件以及数据库操作。讲解了如何利用Gin处理HTTP请求参数,进行数据验证,以及使用Gorm进行数据库连接和操作,同时涵盖了错误处理和返回响应的各种方式。
摘要由CSDN通过智能技术生成

0. 初始化引擎

engine:=gin.Default()

engine.Run(":8090")

1. 数据绑定

1.1 绑定 query 数据

go 参数解析

// 获取 query 中的参数
context.DefaultQuery("key","defaultValue")

// 获取路径参数
// /path/:id
context.Param("id")

// 获取 post form 中的参数
context.PostForm("key")

context.ShouldbBindQuery()

1.2 post 请求参数绑定

var register Register
context.ShouldBind(&register)

type Register struct{
    UserName string `form:"name"`
    Phone string    `form:"phone"`
    Password string `form:"password"`
}

1.3 post json 数据参数绑定

var register Register
context.BindJSON(&register)

1.4 绑定标签


type Param struct{
  Name string `uri:"name" form:"name" header:"name" json:"name" `
}

  • ShouldBindUri: 绑定 uri 使用 ‘uri’ 标签
  • ShouldBindQuery: 绑定 query 使用 ‘form’ 标签
  • ShouldBindHeader: 绑定 header 使用 ‘header’ 标签
  • ShouldBindWith(param, binding.Form): 绑定 form 使用 ‘form’ 标签
  • ShouldBindJSON: 绑定 json 使用 ‘json’ 标签

1.5 多次绑定

要想多次绑定,可以使用 c.ShouldBindBodyWith.
调用此方法,会将 body 中的参数进行缓存,方便下次调用。因为 request.body 中的数据只能被读取一次。

func SomeHandler(c *gin.Context) {
  objA := formA{}
  objB := formB{}
  // 读取 c.Request.Body 并将结果存入上下文。
  if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
    c.String(http.StatusOK, `the body should be formA`)
  // 这时, 复用存储在上下文中的 body。
  } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
    c.String(http.StatusOK, `the body should be formB JSON`)
  // 可以接受其他格式
  } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
    c.String(http.StatusOK, `the body should be formB XML`)
  } else {
    ...
  }
}

1.6 数据验证

Gin使用 go-playground/validator/v10 进行验证。 参考文档
https://pkg.go.dev/github.com/go-playground/validator/v10#section-readme

1.7 文件上传

  • 上传单个文件
func (f *FileController) UploadOne(c *gin.Context) {
	// 单文件
	file, _ := c.FormFile("file")
	log.Println(file.Filename)

	dst := "./upload/" + file.Filename
	// 上传文件至指定的完整文件路径
	c.SaveUploadedFile(file, dst)

	c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
}

  • 上传多个文件
// Multipart form
	form, _ := c.MultipartForm()
	files := form.File["upload[]"]

	for _, file := range files {
		log.Println(file.Filename)
		dst := "./upload/" + file.Filename
		// 上传文件至指定目录
		c.SaveUploadedFile(file, dst)
	}
	c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))

2. 数据返回格式

2.1 返回 string 和 []byte

context.Writer.Write()
context.Writer.WriteString()

2.2 返回 json

map 对象返回

context.Writer.JSON(200,map[string]interface{}{
    "code":1,
    "message":"ok",
    "data":"content"
})

struct 对象返回


type Response struct{
    Code int        `json:"code"`
    Message string  `json:"message"`
    Data interface{} `json:"data"`
}


resp:=Response{Code:1,Message:"ok",Data:"true"}
context.JSON(200,&resp)

2.3 返回 html 模版


// 设置 html 目录
engine.LoadHTMLGlob("./html/*")

// 设置静态资源目录
engine.Static("/img","./img")

// 返回 html 数据
context.HTML(http.StatusOK,"index.html",gin.H{
    "fullPath":fullPath,
})

3. 请求路由组

engine.Group()

4. 中间件 middleware

engine.Use()

4.1 自定义中间件

类似 springboot 中的拦截器
接收到请求后,先进入中间件,然后再进入处理函数
处理函数完成,再次进入中间件,最后返回客户端

  • func 函数
  • 返回类型为 HandleFunc
func RequestInfos() gin.HandleFunc{
    return func(context *gin.Context){

    }
}

// 所有接口都使用中间件
engine.Use(RequestInfos())

// 单个接口使用中间件
engine.GET("/url",RequestInfos(),func (context *gin.Context)){
    // 功能实现
})

context.Next
Next 之前的代码在进入处理函数前执行
Next 之后的代码在处理函数完成后执行

// 进入 handle 前的逻辑

context.Next()

// 执行完 handle 后的逻辑

5. gin 数据库使用

gorm

安装

go get -u githu.com/jinzhu/gorm

连接数据库
不同的数据库需要不同的驱动程序,gorm 提供了一些默认的驱动


import _ "github.com/jinzhu/gorm/dialects/mysql"
// import _ "github.com/jinzhu/gorm/dialects/postgres"
// import _ "github.com/jinzhu/gorm/dialects/sqlite"
// import _ "github.com/jinzhu/gorm/dialects/mssql"

MySql

import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

PostgreSQL

import (
  "gorm.io/driver/postgres"
  "gorm.io/gorm"
)

dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

SQLite

import (
  "gorm.io/driver/sqlite" // Sqlite driver based on GGO
  // "github.com/glebarez/sqlite" // Pure go SQLite driver, checkout https://github.com/glebarez/sqlite for details
  "gorm.io/gorm"
)

// github.com/mattn/go-sqlite3
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})

SQL Server

import (
  "gorm.io/driver/sqlserver"
  "gorm.io/gorm"
)

// github.com/denisenkom/go-mssqldb
dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})

Clickhouse
https://github.com/go-gorm/clickhouse

import (
  "gorm.io/driver/clickhouse"
  "gorm.io/gorm"
)

func main() {
  dsn := "tcp://localhost:9000?database=gorm&username=gorm&password=gorm&read_timeout=10&write_timeout=20"
  db, err := gorm.Open(clickhouse.Open(dsn), &gorm.Config{})

  // Auto Migrate
  db.AutoMigrate(&User{})
  // Set table options
  db.Set("gorm:table_options", "ENGINE=Distributed(cluster, default, hits)").AutoMigrate(&User{})

  // 插入
  db.Create(&user)

  // 查询
  db.Find(&user, "id = ?", 10)

  // 批量插入
  var users = []User{user1, user2, user3}
  db.Create(&users)
  // ...
}

连接池
GORM 使用 database/sql 维护连接池

sqlDB, err := db.DB()

// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)

// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)

// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

模型定义


type Model struct{
    Id uint `gorm:"primary_key"`
    Name string
}

// 默认表名是结构体名称的复数 models
// 自定义表名
func (m Model)TableName()string{
    return "model"
}


// 自定义列名
type User struct{
    Id string `gorm:"primary_key"`
    Name string `gorm:"column:name"`
    CreateTime time.Time `gorm:"column:create_time"`
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值