当前位置:网站首页>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, "删除用户")
}
边栏推荐
- Transformation transformation operator
- What are the differences between Oracle Linux and CentOS?
- Boot - Prometheus push gateway use
- 数据手册中的词汇
- C language instance_ four
- LeetCode:1175. Prime permutation
- 736. LISP syntax parsing: DFS simulation questions
- taro3.*中使用 dva 入门级别的哦
- golang中的atomic,以及CAS操作
- Force buckle 1037 Effective boomerang
猜你喜欢
JTAG debugging experience of arm bare board debugging
Your cache folder contains root-owned files, due to a bug in npm ERR! previous versions of npm which
Body mass index program, entry to write dead applet project
Clickhouse fields are grouped and aggregated, and SQL is queried according to the granularity of any time period
从底层结构开始学习FPGA----FIFO IP的定制与测试
Transplant DAC chip mcp4725 to nuc980
Can the system hibernation file be deleted? How to delete the system hibernation file
2022 Google CTF SEGFAULT LABYRINTH wp
Your cache folder contains root-owned files, due to a bug in npm ERR! previous versions of npm which
According to the analysis of the Internet industry in 2022, how to choose a suitable position?
随机推荐
Sword finger offer II 035 Minimum time difference - quick sort plus data conversion
黑马笔记---创建不可变集合与Stream流
taro3.*中使用 dva 入门级别的哦
C language instance_ five
swiper组件中使用video导致全屏错位
对C语言数组的再认识
Taro2.* 小程序配置分享微信朋友圈
Neon Optimization: an instruction optimization case of matrix transpose
C # method of calculating lunar calendar date 2022
NEON优化:性能优化经验总结
Yunna | work order management software, work order management software app
WCF基金会
Transformation transformation operator
Taro2.* applet configuration sharing wechat circle of friends
Case development of landlord fighting game
C language - array
THREE. AxesHelper is not a constructor
Installation of gazebo & connection with ROS
Js逆向——捅了【马蜂窝】的ob混淆与加速乐
负载均衡性能参数如何测评?