网站首页 » Golang,gin » Gin 从零开始搭建gin项目框架

Gin 从零开始搭建gin项目框架

March 25, 2021 Golang,gin

一、创建项目

新建文件夹 test

进入文件夹,在终端执行

go mod init 

go mod init 是使用go module 的管理包,前提是设置做了以下设置

GO111MODULE = on
GOPROXY=https://goproxy.cn,direct

执行 go mod init 后, 将在 test 文件夹下生成 go.mod 文件, 将会包含以下信息:模块名和go 版本

module awesomeProject/test

go 1.16

test 文件夹下创建相应的文件夹

2021-03-25T03:22:43.png

- test
|- - api //接口控制器包
|- - - controller.go //控制器文件
|- - common //公共函数包
| - - - functions.go //公共函数文件
|- - config //配置文件包
| - - - config.go //配置加载文件
| - - - config.yml //配置文件
|- - model //模型文件包
| - - - database.go //数据库连接初始化文件
| - - - pw_member.go //表模型文件
|- - resource // 静态文件夹
|- - route //路由文件包
| - - - router.go //路由配置文件
main.go // 入口文件 (图片显示 go-main.go 是我自己定义的文件,改成main.go即可)
go.mod // go 依赖管理文件

二、下载相关的包

  • gin下载
go get -u github.com/gin-gonic/gin

gin 就是我们要使用的web 框架, 当然是要下载

  • viper 下载
go get github.com/spf13/viper

viper 是很好用配置控制包, 最关键的是可以监听配置参数改动,配置项发生改变无需重启服务

  • mysql 驱动下载
go get -u github.com/go-sql-driver/mysql
  • gorm 下载
go get -u gorm.io/gorm

上述安装完成后,可以在go.mod文件中看到我们依赖的所有包

2021-03-25T03:13:36.png

三、代码编写

逻辑代码编写部分,我们从 go-main.go 文件开始讲解

go-main.go

package main

import (
    "awesomeProject/test/config"
    "awesomeProject/test/model"
    "awesomeProject/test/route"
    "github.com/gin-gonic/gin"
    "github.com/spf13/viper"
)

func main() {
    r := route.InitRouter()

    //加载配置文件
    config.InitConfig()

    // 创建数据库连接
    model.InitDb()
    // defer关键字,当API访问结束时,关闭数据库连接
    defer model.Db.Close()

    //监听8000端口
    gin.SetMode(viper.GetString("server.run_mode"))
    r.Run(viper.GetString("server.addr"))
}

作为服务的入口文件,go-main.go 会开启web服务, 下面按照 go-main.go 文件的代码顺序依次讲解作用

r := route.InitRouter()   
// 定义了路由,route包中的InitRouter函数完成了路由配置,即url与控制器的对应

此处穿插介绍一下 golang 引用包的顺序
2021-03-25T03:19:27.png

完毕!


r := route.InitRouter()
route包下 router.go 文件 InitRouter 函数

package route

// 路由包

import (
    "awesomeProject/test/api"
    "github.com/gin-gonic/gin"
)

func InitRouter() *gin.Engine {
    router := gin.Default()

    // 首页路由
    router.GET("/", api.GetIndex)
    // post测试路由
    router.POST("/test",api.PostTest)
    // 测试数据库操作
    router.GET("/testsql", api.GetTestSql)

    return router
}

// 如果有新的接口,需要再函数内添加url 与 控制器的对应关系

config.InitConfig()
config 包下config.go文件 InitConfig函数

package config

import "github.com/spf13/viper"

func InitConfig() {
    viper.AddConfigPath("./config")
    viper.SetConfigName("config")
    viper.SetConfigType("yaml")

    if err := viper.ReadInConfig();err != nil {
        if _, ok := err.(viper.ConfigFileNotFoundError); ok {
            panic("未找到配置文件")
        } else {
            panic("加载配置文件失败")
        }
    }
    // 监听配置文件变化
    viper.WatchConfig()
}

// 配置viper包

model.InitDb()
model包下database文件 InitDb函数

package model

import (
    "fmt"

    "github.com/spf13/viper"
    _ "github.com/go-sql-driver/mysql"
    "github.com/jinzhu/gorm"
)

// 公共Db对象
var Db *gorm.DB

func InitDb() {

    driverName := viper.GetString("db.driver_name")
    host := viper.GetString("db.host")
    port := viper.GetString("db.port")
    database := viper.GetString("db.database")
    username := viper.GetString("db.username")
    password := viper.GetString("db.password")
    charset := viper.GetString("db.charset")
    args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=true",
        username,
        password,
        host,
        port,
        database,
        charset,
    )

    db, err := gorm.Open(driverName, args)
    if err != nil {
        panic("failed to connect database,err:" + err.Error())
    }
    Db = db
}
// 从viper中取出数据库配置,连接数据库. 文件中定义了Db , 根据golang包引用规则,Db可以在其他地方调用。所以可以在模型文件中使用model.Db对象 进行数据库操作

defer model.Db.Close() defer 关键字,在main函数最后执行,当一次访问结束后,关闭数据库连接。

三、根据接口访问,依次介绍不同的文件

在上述router.go 中,我们定义好了url与控制器的对应关系。
controller.go

package api

// 控制器包

import (
    "awesomeProject/test/common"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/spf13/viper"
)

// 首页控制器
func GetIndex(c *gin.Context) {
    // 传入code参数
    code := c.DefaultQuery("code", "0")
    var backdata map[string]interface{}
    if code == "0" {
        common.CommonFail(c, backdata, "code值缺少")
    } else {
        backdata, status :=common.GetAuth2Session(code)
        if status == 0 {
            common.CommonFail(c, backdata, "code 验证失败")
        } else {
            common.CommonSuccess(c, backdata)
        }
    }
}


// 测试控制器
func PostTest(c * gin.Context)  {

    //data := make(map[string]interface{})
    //
    //data["foo"] = "bar"
    //fmt.Println(data)
    //c.JSON(200, data)
    //common.CommonFail(c, rest, "失败了")
}


// 测试数据库操作
func GetTestSql(c *gin.Context) {

    //model.AddMember()
    //fmt.Println("执行完成")

    fmt.Println(viper.GetString("wx.appid"))

}

当我们访问 http://localhost:8080/testsql 时,根据路由的映射,我们访问到了GetTestSql方法。我们在model/pw_member.go模型文件中添加一条用户信息

pw_member.go

package model

import "fmt"

type Pw_member struct {
    Id int
    Name string
    Age int
    Sex int
}


// 设置表名
func (Pw_member) TableName() string {
    return "pw_member"
}

// 添加一行数据
func AddMember()  {
    member := Pw_member{Name: "zhangsan", Age: 18, Sex: 1}

    result := Db.Create(&member)
    fmt.Println(member.Id)
    fmt.Println(result.RowsAffected)
    fmt.Println(result.Error)

}

四、viper包配置项介绍

在整个项目的截图中,还有一个文件 config/config.yml 未介绍,由于跟viper 有关系,我们单独来介绍一下

配置文件加载我们知道是在 config/config.go 中完成,那配置项在哪设置呢? 答案就是在config.yml
config.yml


server:
  run_mode: debug
  addr: :8000
wx:
  appid: 112212
  secret: 222222
db:
  driver_name: mysql
  host: 127.0.0.1
  port: 3306
  database: test
  username: root
  password: root
  charset: utf8

viper相关的使用教程,就请大家自行百度吧。

添加新评论