Golang - Gin框架学习笔记
Gin简介
1.Gin 是什么?
Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,可以使用 Gin 。
2.Gin特点
轻量级、高性能(使用httprouter)、中文文档齐全、简单易用。
3.Gin相关地址
doc:https://gin-gonic.com/zh-cn/docs/
github:https://github.com/gin-gonic/gin
快速开始
1. 用module模式创建工程
mkdir web_api
cd web_api
go mod init web_api
2.创建main.go
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
3. 运行
go run main.go
4. 浏览器打开 127.0.0.1:8080/ping
实践
1. 说明
1)这是一个简单的例子,实现了通过id查找数据库获取用户名字的功能。
2)使用了MVC结构,当然也可以不套用这种结构,好处就是开发web程序结构会清晰很多。
3)使用了go modules的包管理方式,确实很方便。
4)依赖了yml和gorm库
2.目录结构如下
│ config.yml
│ go.mod
│ go.sum
│ main.go
│ Makefile
│ README.md
├─app
│ app.go
│ handle.go
│ routers.go
│
├─controllers
│ user.go
│
├─models
│ model.go
│ user.go
│
├─routers
│ router.go
│
└─service
user.go
3.主要文件说明
1)app/app.go 应用程序文件,负责初始化gin上下文,处理信号量
package app
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"web_api/routers"
"github.com/gin-gonic/gin"
)
type Config struct {
Port string
Debug bool
}
func Run(cfg Config) {
router := gin.Default()
routes.RegisterRouters(router)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: router,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutdown Server ...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
}
2) controllers/user.go 控制文件,获取请求参数,调用service的逻辑方法,然后返回结果
package controllers
import (
"net/http"
"web_api/service"
"github.com/gin-gonic/gin"
)
func GetName(c *gin.Context) {
id := c.Param("id")
r := service.User{ID: id}
name, err := r.GetName()
if nil != err {
c.String(http.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, gin.H{"error": "ok", "name": name})
}
3) models/model.go 数据库的初始化
package models
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// Config 配置
type Config struct {
User string
Password string
Host string
Name string
}
var (
db *gorm.DB
)
// Setup initializes the database instance
func Setup(cfg Config) error {
var err error
db, err = gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
cfg.User,
cfg.Password,
cfg.Host,
cfg.Name))
if err != nil {
return err
}
db.SingularTable(true)
db.DB().SetMaxIdleConns(56)
db.DB().SetMaxOpenConns(128)
return nil
}
// CloseDB closes database connection (unnecessary)
func CloseDB() {
defer db.Close()
}
4) models/user.go user 数据库表的增删改查
package models
import (
"github.com/jinzhu/gorm"
)
type User struct {
ID string `gorm:"primary_key;type:INT(20)"`
Age int32 `gorm:"type:INT(20)"`
Name string `gorm:"type:VARCHAR(256)"`
Desc string `gorm:"type:VARCHAR(256)"`
}
func (User) TableName() string {
return "user"
}
func GetUser(id string) (*User, error) {
u := &User{
ID: id,
}
err := db.First(u).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return u, nil
}
5) routers/router.go 定义路由
package routers
import (
"web_api/controllers"
"github.com/gin-gonic/gin"
)
// RegisterRouters ...
func RegisterRouters(g *gin.Engine) {
g.GET("/name/:id", controllers.GetName)
}
6) service/user.go user的逻辑
package service
import (
"web_api/models"
)
type User struct {
ID string
}
func (r *User) GetName() (string, error) {
u, err := models.GetUser(r.ID)
if nil != err {
return "", err
}
return u.Name, nil
}
7) main.go
package main
import (
"flag"
"io/ioutil"
"log"
"web_api/app"
"web_api/models"
"gopkg.in/yaml.v2"
)
// Config 配置
type Config struct {
App app.Config
Model models.Config
}
var (
cfgPath = flag.String("config", "config.yml", "config file path")
)
func main() {
cfg := Config{}
if data, err := ioutil.ReadFile(*cfgPath); nil != err {
panic(err)
} else {
if err := yaml.Unmarshal(data, &cfg); nil != err {
panic(err)
}
}
if err := models.Setup(cfg.Model); nil != err {
panic(err)
}
app.Run(cfg.App)
log.Println("Server exiting")
}
4.配置文件 confg.yml
app:
port: 8080
debug: true
model:
user: root
password: xxxxx
host: 127.0.0.1:3306
name: mydb
5.测试
1)需要你的mysql有个叫mydb的库,里有一张叫user的表
2)查找id为1000的人的名字,浏览器打开 http://127.0.0.1:8080/name/1000
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」