声明:本站文章均为作者个人原创,图片均为实际截图。如有需要请收藏网站,禁止转载,谢谢配合!!!

Gin是一个使用Go语言开发的Web框架。
它提供类似Martini的API,但性能更佳,速度提升高达40倍。
如果你是性能和高效的追求者, 你会爱上 Gin。

  • 快速
    基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。

  • 支持中间件
    传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。

  • Crash 处理
    Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!

  • JSON 验证
    Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。

  • 路由组
    Gin帮助您更好地组织您的路由,例如,按照需要授权和不需要授权和不同API版本进行分组。此外,路由分组可以无限嵌套而不降低性能。

  • 错误管理
    Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。

  • 内置渲染
    Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。

  • 可扩展性
    新建一个中间件非常简单

一个todolist的项目

原始项目

package main

import(
    "github.com/gin-gonic/gin"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

type Todo struct{
    ID int `json:"id"`
    Title string `json:"title"`
    Status bool `json:"status"`
}

var(
    DB *gorm.DB
)

func InitMySql() (err error) {
    dsn := "root:root123@tcp(127.0.0.1:3306)/list?charset=utf8mb4&parseTime=True&loc=Local"
    DB1, err := gorm.Open("mysql", dsn)
    if err != nil {
        return
    }
    DB = DB1
    return DB1.DB().Ping()
}

func main(){

    //连接数据库
    err := InitMySql()
    if err != nil{
        panic(err)
    }
    defer DB.Close()

    //定义路由
    r := gin.Default()
    r.Static("/static", "static")
    r.LoadHTMLGlob("templates/*")
    r.GET("/", controller.IndexHandler)
    v1Group := r.Group("v1")
    {
        v1Group.POST("/todo", function(c *gin.Context){ ... })
        v1Group.GET("/todo",  function(c *gin.Context){ ... })
        v1Group.PUT("/todo/:id",  function(c *gin.Context){ ... })
        v1Group.DELETE("/todo/:id",  function(c *gin.Context){ ... })
    }

    r.Run()

}

拆分目标和步骤

dao 主要用于数据库等的连接初始化
model 主要用于数据的curd
controller 主要用于路由中绑定的处理过程
router 主要用于封装路由列表

1、dao(dao\mysql.go)主要用于数据库等的连接初始化

package dao

import (
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

var(
    DB *gorm.DB
)

func Close()  {
    DB.Close()
}

func InitMySql() (err error) {
    dsn := "root:root123@tcp(127.0.0.1:3306)/list?charset=utf8mb4&parseTime=True&loc=Local"
    DB1, err := gorm.Open("mysql", dsn)
    if err != nil {
        return
    }
    DB = DB1
    return DB1.DB().Ping()
}

2、model(model\todo.go)

package model

import (
    "list/dao"
)

type Todo struct{
    ID int `json:"id"`
    Title string `json:"title"`
    Status bool `json:"status"`
}

func CreateATodo(todo *Todo) (err error) {
    err = dao.DB.Create(&todo).Error
    return
}

func GetTodoList() (todoList []*Todo, err error){
    if err = dao.DB.Find(&todoList).Error; err != nil{
        return nil, err
    }
    return
}

func GetATodo(id string)(todo *Todo, err error)  {
    todo = new(Todo)
    if err = dao.DB.Where("id=?", id).First(todo).Error; err != nil{
        return nil, err
    }
    return
}

func UpdateATodo(todo *Todo)(err error)  {
    err = dao.DB.Save(todo).Error
    return
}

func DeleteATodo(id string) (err error){
    err = dao.DB.Where("id=?" , id).Delete(&Todo{}).Error
    return
}

3、controller(controller\controller.go)

package controller

import (
    "github.com/gin-gonic/gin"
    "list/model"
)

func IndexHandler(c *gin.Context) {
    c.HTML(200, "index.html", nil)
}

func CreateATodo(c *gin.Context) {

    var todo model.Todo
    c.BindJSON(&todo)

    if err := model.CreateATodo(&todo); err != nil{
        c.JSON(200, gin.H{"error": err.Error()})
    }else{
        c.JSON(200, todo)
    }
}

func GetTodoList(c *gin.Context) {
    if todoList, err := model.GetTodoList(); err != nil{
        c.JSON(200, gin.H{"error": err.Error()})
    }else{
        c.JSON(200, todoList)
    }
}

func UpdateATodo(c *gin.Context) {
    id,ok := c.Params.Get("id")
    if !ok{
        c.JSON(200, gin.H{"error":"缺少id"})
        return
    }

    todo,err := model.GetATodo(id)

    if err != nil{
        c.JSON(200, gin.H{"error":"查找失败"})
        return
    }
    c.BindJSON(&todo)

    if err2 := model.UpdateATodo(todo); err2 != nil{
        c.JSON(200, gin.H{"error": err2.Error()})
    }else{
        c.JSON(200, todo)
    }
}

func DeleteATodo(c *gin.Context) {
    id, ok := c.Params.Get("id")
    if !ok {
        c.JSON(200, gin.H{"error":"missing id"})
        return
    }
    if err := model.DeleteATodo(id); err != nil{
        c.JSON(200, gin.H{"error:":err.Error()})
    }else{
        c.JSON(200, gin.H{"msg":"删除成功"})
    }

}

4、router(router\router.go)

package routers

import (
    "github.com/gin-gonic/gin"
    "list/controller"
)

func SetUpRoute() *gin.Engine {
    r := gin.Default()

    r.Static("/static", "static")
    r.LoadHTMLGlob("templates/*")
    r.GET("/", controller.IndexHandler)
    v1Group := r.Group("v1")
    {
        v1Group.POST("/todo", controller.CreateATodo)
        v1Group.GET("/todo", controller.GetTodoList)
        v1Group.PUT("/todo/:id", controller.UpdateATodo)
        v1Group.DELETE("/todo/:id", controller.DeleteATodo)
    }
    return r
}

main.go

package main

import(
    "list/dao"
    "list/model"
    "list/routers"
)

func main()  {
    err := dao.InitMySql()
    if err != nil{
        panic(err)
    }

    defer dao.Close()
    dao.DB.AutoMigrate(&model.Todo{})
    r := routers.SetUpRoute()
    r.Run()
}

可以看到main.go代码清爽了很多