当前位置:网站首页>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 中间件来实现
安装方式:
go get github.com/gin-contrib/sessions文件
~/go/go-gin2/gindemo01/main.go
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 是通过实例对象的语法,完成关系型数据库的操作的技术、是对象映射的缩写
文件
~/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, "删除用户")
}
边栏推荐
- Table table setting fillet
- C # method of calculating lunar calendar date 2022
- Metauniverse urban legend 02: metaphor of the number one player
- c语言—数组
- 7.6 simulation summary
- Taro applet enables wxml code compression
- 1123. The nearest common ancestor of the deepest leaf node
- Lldp compatible CDP function configuration
- Analysis of mutex principle in golang
- 字节P7专业级讲解:接口测试常用工具及测试方法,福利文
猜你喜欢

子网划分、构造超网 典型题

黑马笔记---创建不可变集合与Stream流

一起看看matlab工具箱内部是如何实现BP神经网络的

云呐|工单管理办法,如何开展工单管理

405 method not allowed appears when the third party jumps to the website

Typical problems of subnet division and super network construction

AI 从代码中自动生成注释文档

According to the analysis of the Internet industry in 2022, how to choose a suitable position?

Can the system hibernation file be deleted? How to delete the system hibernation file

c语言—数组
随机推荐
Neon Optimization: About Cross access and reverse cross access
Installation and testing of pyflink
What does front-end processor mean? What is the main function? What is the difference with fortress machine?
Gazebo的安装&与ROS的连接
[chip scheme design] pulse oximeter
Case development of landlord fighting game
Failed to successfully launch or connect to a child MSBuild. exe process. Verify that the MSBuild. exe
HMM 笔记
POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
Realize incremental data synchronization between MySQL and ES
WCF基金会
2022 Google CTF SEGFAULT LABYRINTH wp
HMM notes
MySQL script batch queries all tables containing specified field types in the database
736. Lisp 语法解析 : DFS 模拟题
According to the analysis of the Internet industry in 2022, how to choose a suitable position?
NEON优化:性能优化常见问题QA
图片打水印 缩放 和一个输入流的转换
Spark TPCDS Data Gen
搭建【Redis in CentOS7.x】