当前位置:网站首页>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, "删除用户")
}
边栏推荐
猜你喜欢
随机推荐
[advanced C language] 8 written questions of pointer
C语言实例_4
Atomic in golang, and cas Operations
Neon Optimization: About Cross access and reverse cross access
NEON优化:性能优化经验总结
Yunna | work order management software, work order management software app
Let's see through the network i/o model from beginning to end
NEON优化:性能优化常见问题QA
对C语言数组的再认识
剑指 Offer II 035. 最小时间差-快速排序加数据转换
2022 Google CTF segfault Labyrinth WP
从零开始匹配vim(0)——vimscript 简介
ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】
Installation and testing of pyflink
第三方跳转网站 出现 405 Method Not Allowed
修改px4飞控的系统时间
POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
Vocabulary in Data Book
Go zero micro service practical series (IX. ultimate optimization of seckill performance)
Start from the bottom structure to learn the customization and testing of fpga---- FIFO IP








