当前位置:网站首页>Gin 入门实战

Gin 入门实战

2022-07-06 18:01:00 hualaoshuan

1. 环境搭建、热加载;

# 下载 gin 
cd ~/go/go-gin2
go get -u github.com/gin-gonic/gin

# 如果无法下载,尝试
go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

# 项目准备(使用 go.mod 管理项目)
cd ~/go/go-gin2/gindemo01
go mod init gindemo01

# 代码写完后编译
go run main.go

# 第三方热加载
# 文档:https://github.com/gravityblast/fresh
export GOPROXY=https://goproxy.io
go get -u github.com/pilu/fresh
# fresh 放入项目文件夹,会在当前目录生成 tmp 目录:
fresh
  • 文件 ~/go/go-gin2/gindemo01/main.go
package main

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

func main() {
    
	// 创建默认路由引擎
 	r := gin.Default()

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

 	// 创建 web 服务,默认 8080 端口
 	r.Run(":8001")
}

2. 响应数据;

  • 文件 ~/go/go-gin2/gindemo01/templates/index.html
<h1>{
   {.title}}</h1>
  • 文件 ~/go/go-gin2/gindemo01/main.go
package main

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

type Article struct {
    
	Title string `json:"title"`
	Desc string `json:"desc"`
	Content string `json:"content"`
}

func main() {
    
	// 创建默认路由引擎
 	r := gin.Default()

	// 配置模板路径
	r.LoadHTMLGlob("templates/*")

 	// 配置路由
 	r.GET("/", func(c *gin.Context) {
    
 		// 返回字符串
		c.String(http.StatusOK, "值:%v", "首页")

		// 返回json
 		c.JSON(http.StatusOK, map[string]interface{
    }{
    
 			"success" : true,
 			"msg": "完成",
		})

		// 内置方法返回 json
		c.JSON(http.StatusOK, gin.H{
    
			"success" : true,
			"msg": "完成2",
		})

		// 实例化结构体数据
		a := &Article{
    
			"标题",
			"介绍",
			"内容",
		}
		c.JSON(http.StatusOK, a)
		// {"title":"标题","desc":"介绍","content":"内容"}

		// 返回jsonp
		// http://localhost:8001/?callback=12
		c.JSONP(http.StatusOK, a)

		// 返回 xml
		c.XML(http.StatusOK, gin.H{
    
			"success" : false,
			"msg": "xml",
		})

		// 渲染 html
		c.HTML(http.StatusOK, "index.html", gin.H{
    
			"title" : "首页1",
		})

	})

 	// 创建 web 服务,默认 8080 端口
 	r.Run(":8001")
}

3. 路由传值;

  • 文件 ~/go/go-gin2/gindemo01/main.go
package main

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

type UserInfo struct {
    
	Username string `json:"username" form:"username"`
	Passwd string `json:"passwd" form:"passwd"`
	Age string `json:"age" form:"age"`
}

func main() {
    
	// 创建默认路由引擎
 	r := gin.Default()

 	// 获取 get 传值
 	r.GET("/user", func(c *gin.Context) {
    
		username := c.Query("username")
		page := c.DefaultQuery("page","1")

		// http://localhost:8001/user?username=hua
		c.JSON(http.StatusOK, gin.H{
    
			"username" : username,
			"page": page,
		})
	})

 	// 获取"表单"的 post 传值
 	r.POST("/addUser", func(c *gin.Context) {
    
		username := c.PostForm("username")
		passwd := c.PostForm("passwd")
 		age := c.DefaultPostForm("age", "20")

 		c.JSON(http.StatusOK, gin.H{
    
 			"username" : username,
 			"passwd": passwd,
 			"age": age,
		})
	})


	//绑定到结构体
	// http://localhost:8001/getUser?username=hua&passwd=123456
	r.GET("/getUser", func(c *gin.Context) {
    
		user := &UserInfo{
    }
		if err := c.ShouldBind(&user); err==nil {
    
			fmt.Printf("%#v", user) // 打印
			c.JSON(http.StatusOK, user)
		} else {
    
			c.JSON(http.StatusOK, gin.H{
    
				"err": err.Error(),
			})
		}
	})

	r.POST("/addUser2", func(c *gin.Context) {
    
		user := &UserInfo{
    }
		if err := c.ShouldBind(&user); err==nil {
    
			fmt.Printf("%#v", user) // 打印
			c.JSON(http.StatusOK, user)
		} else {
    
			c.JSON(http.StatusOK, gin.H{
    
				"err": err.Error(),
			})
		}
	})

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

 	// 创建 web 服务,默认 8080 端口
 	r.Run(":8001")
}

4. 路由分组:

在这里插入图片描述

  • 文件 ~/go/go-gin2/gindemo01/routers/defaultRouters.go
package routers

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

func DefaultRoutersInit (r *gin.Engine) {
    
	defaultRouters := r.Group("/")
	{
    
		defaultRouters.GET("/", func(c *gin.Context) {
    
			c.String(http.StatusOK, "首页")
		})
	}
}
  • 文件 ~/go/go-gin2/gindemo01/main.go
package main

import (
	"gindemo01/routers"
	"github.com/gin-gonic/gin"

)

func main() {
    
	// 创建默认路由引擎
	var r = gin.Default() 

	//路由分组
	routers.DefaultRoutersInit(r)

 	// 创建 web 服务,默认 8080 端口
 	r.Run(":8001")
}

5. 自定义控制器、控制器的继承;

在这里插入图片描述

  • 文件 ~/go/go-gin2/gindemo01/controllers/baseControllers.go
package _default

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

type BaseController struct {
    

}

func (con BaseController) success (c *gin.Context) {
    
	c.String(http.StatusOK, "ok")
}

func (con BaseController) error (c *gin.Context) {
    
	c.String(http.StatusOK, "error")
}
  • 文件 ~/go/go-gin2/gindemo01/controllers/userControllers.go
package _default

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

type UserController struct{
    
	BaseController	// 控制器继承
}

func (con UserController) Index (c *gin.Context) {
    
	c.String(http.StatusOK, "用户列表")
}

func (con UserController) Add (c *gin.Context) {
    
	c.String(http.StatusOK, "添加用户")
	con.success(c)
}
  • 文件 ~/go/go-gin2/gindemo01/routers/defaultRouters.go
package routers

import (
	_default "gindemo01/controllers/default"
	"github.com/gin-gonic/gin"
	"net/http"
)

func DefaultRoutersInit (r *gin.Engine) {
    
	defaultRouters := r.Group("/")
	{
    
		defaultRouters.GET("/", func(c *gin.Context) {
    
			c.String(http.StatusOK, "首页")
		})
		
		// 用户列表
		// UserIndex() 执行方法,不加括号是注册方法
		defaultRouters.GET("/user", _default.UserController{
    }.Index)

		// 添加用户
		defaultRouters.GET("/user/add", _default.UserController{
    }.Add)
	}
}

6. 路由中间件;

在这里插入图片描述
如果在中间件中使用了 goroutine:

  • 当在中间件或者 handler 中启动新的 goroutine 时,不能使用原始的上下文 c *gin.Context,必须使用其只读副本 c.Copy()

  • 文件 ~/go/go-gin2/gindemo01/middlewares/init.go

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", "zhang")

	// 定义协程统计日志
	cc := c.Copy()
	go func() {
    
		time.Sleep(2 * time.Second)
		fmt.Println("Done! in path " + cc.Request.URL.Path)
	}()

}
  • 文件 ~/go/go-gin2/gindemo01/routers/defaultRouters.go
package routers

import (
	"fmt"
	_default "gindemo01/controllers/default"
	"gindemo01/middlewares"
	"github.com/gin-gonic/gin"
	"net/http"
)

func DefaultRoutersInit (r *gin.Engine) {
    


	defaultRouters := r.Group("/")
	// 配置全局中间件
	defaultRouters.Use(middlewares.InitMiddleware)
	{
    
		defaultRouters.GET("/", func(c *gin.Context) {
    
			// 获取中间件的数据
			username, _ := c.Get("username")
			fmt.Println(username)

			// 类型断言
			v, ok := username.(string)
			if ok == true {
    
				fmt.Println("用户名称:" +v)
			} else {
    
				fmt.Println("获取用户失败")
			}

			c.String(http.StatusOK, "首页")
		})

		// 用户列表
		// UserIndex() 执行方法,不加括号是注册方法
		defaultRouters.GET("/user", _default.UserController{
    }.Index)

		// 添加用户
		defaultRouters.GET("/user/add", _default.UserController{
    }.Add)
	}
}

7. 自定义 Model;

关于 Model

  • 如果应用非常简单的话,可以在 Controller 里面处理常见的业务逻辑。但是如果有一个功能想在多个控制器、或者多个模板里面复用的话,就可以把公共的功能单独抽取出来作为一个模块(Model)。Model 是逐步抽象的过程,一般会在 Model 里封装一些公共的方法让不同 Controller 使用,也可以砸 Model 中实现和数据打交道

  • 文件 ~/go/go-gin2/gindemo01/models/tools.go

package models

import (
	"time"
)

// 时间转化成日期
func UnixToTime(timestamp int) string {
    
	t := time.Unix(int64(timestamp), 0)
	return t.Format("2006-01-02 15:04:05")
}
  • 调用:
time := models.UnixToTime(1653639435)
fmt.Println("当前时间:"+time)

8. Session 获取:

Gin 没有提供 session 相关的文档,需要第三方 session 中间件来实现

package main

import (
	"gindemo01/routers"
	"github.com/gin-contrib/sessions/redis"
	"github.com/gin-gonic/gin"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
)

func main() {
    
	// 创建默认路由引擎
	var r = gin.Default()

	// 配置 session 中间件
	// 创建基于 cookie 的存储引擎,secret 参数是用于加密的秘钥
	store := cookie.NewStore([]byte("secret"))
	// 配置 session 中间件,store 是前面创建的存储引擎
	r.Use(sessions.Sessions("mysession", store))

	//配置 redis 存储引擎
	store_redis, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	r.Use(sessions.Sessions("mysession_redis", store_redis))

	//路由分组
	routers.DefaultRoutersInit(r)
	routers.ApiRoutersInit(r)

 	// 创建 web 服务,默认 8080 端口
 	r.Run(":8001")
}
  • 文件 ~/go/go-gin2/gindemo01/controllers/default/userController.go
package _default

import (
	"fmt"
	"gindemo01/models"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"net/http"
)

type UserController struct{
    
	BaseController	// 控制器继承
}

func (con UserController) Index (c *gin.Context) {
    
	session := sessions.Default(c)
	// 设置过期时间等
	session.Options(sessions.Options{
    
		MaxAge: 3600 * 6,
	})

	// 设置 session
	session.Set("username1", "hua")
	session.Save()	//保存

	// 获取 session
	username := session.Get("username1")
	c.String(http.StatusOK, "username=%v", username)

	time := models.UnixToTime(1653639435)
	fmt.Println("当前时间:"+time)
	c.String(http.StatusOK, "用户列表")
}

func (con UserController) Add (c *gin.Context) {
    
	c.String(http.StatusOK, "添加用户")
	con.success(c)
}

9. 使用 GORM 操作数据库;

简介

  • GORM 是 golang 的一个 orm 框架,orm 是通过实例对象的语法,完成关系型数据库的操作的技术、是对象映射的缩写

  • 文档:https://gorm.io/zh_CN/docs/index.html

  • 文件 ~/go/go-gin2/gindemo01/models/core.go

package models

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

var DB *gorm.DB
var err error

func init () {
    
	// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
	dsn := "root:[email protected](127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
    })

	if err != nil {
    
		fmt.Println(err)
	}
}
  • 文件 ~/go/go-gin2/gindemo01/models/user.go
package models

// 结构体首字母大写
// 和数据表名称对应,比如表为 user_info 结构体定义为 UserInfo
// 默认情况下表名是接口体的复数形式
type User struct {
    
	Id int
	Username string
	Age int
	Email string
	AddTime string
}

// 修改结构体的默认表名称,配置数据表
func (User) TableName() string {
    
	return "user"
}
  • 文件 ~/go/go-gin2/gindemo01/controllers/default/userController.go
package _default

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

type UserController struct{
    
	BaseController	// 控制器继承
}

func (con UserController) Index (c *gin.Context) {
    
	user := []models.User{
    }	// 定义切片
	//models.DB.Find(&user)
	models.DB.Where("age>20").Find(&user)
	c.JSON(http.StatusOK, gin.H{
    
		"result" : user,
	})
}

func (con UserController) Add (c *gin.Context) {
    
	c.String(http.StatusOK, "添加用户")
	con.success(c)
}

func (con UserController) Edit (c *gin.Context) {
    
	c.String(http.StatusOK, "修改用户")
}

func (con UserController) Delete (c *gin.Context) {
    
	c.String(http.StatusOK, "删除用户")
}
原网站

版权声明
本文为[hualaoshuan]所创,转载请带上原文链接,感谢
https://blog.csdn.net/hualaoshuan/article/details/124943890