GoFiber 从零系列(一):项目创建&配置文件&gorm-mysql

GitHub项目地址

GoFiber 从零系列(一):项目创建&配置文件&gorm-mysql

GoFiber 从零系列(二):热加载/热更新 && 日志系统 && 验证入参

起步

通过创建文件夹并在文件夹内运行 go mod init github.com/your/repo,来初始化项目,然后使用 go get 命令安装 Fiber:

go get -u github.com/gofiber/fiber/v2

选用 go-ini/ini编写配置

go get -u github.com/go-ini/ini

一、Hello World

新建文件夹conf,创建app.ini

RUN_MODE = dev

[app]
PAGE_SIZE = 10
JWT_SECRET = 23347$040412
JWT_SALT = jinpika

[server]
HTTP_PORT = 9999
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60

[database]
TYPE = mysql
USER = 数据库账号
PASSWORD = 数据库密码
#127.0.0.1:3306
HOST = 127.0.0.1:3306
NAME = 数据库名

新建文件夹pkg,创建子文件夹setting,创建setting.go

package setting

import (
	"log"
	"time"

	"github.com/go-ini/ini"
)

var (
	Cfg *ini.File

	RunMode string

	HTTPPort int
	ReadTimeout time.Duration
	WriteTimeout time.Duration

	PageSize int
	JwtSecret string
)

func init() {
	var err error
	Cfg, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Fatal("Fail to parse 'conf/app.ini': %v", err)
	}

	LoadBase()
	LoadServer()
	LoadApp()
}

func LoadBase() {
	RunMode = Cfg.Section("").Key("RUN_MODE").MustString("dev")
}

func LoadServer() {
	sec, err := Cfg.GetSection("server")
	if err != nil {
		log.Fatal("Fail to get section 'server': %v", err)
	}

	HTTPPort = sec.Key("HTTP_PORT").MustInt(8000)
	ReadTimeout = time.Duration(sec.Key("READ_TIMEOUT").MustInt(60)) * time.Second
	WriteTimeout =  time.Duration(sec.Key("WRITE_TIMEOUT").MustInt(60)) * time.Second
}

func LoadApp() {
	sec, err := Cfg.GetSection("app")
	if err != nil {
		log.Fatal("Fail to get section 'app': %v", err)
	}

	JwtSecret = sec.Key("JWT_SECRET").MustString("!@)*#)!@U#@*!@!)")
	PageSize = sec.Key("PAGE_SIZE").MustInt(10)
}

在根目录创建main.go

package main

import (
	"fmt"

	"github.com/gofiber/fiber/v2"
	"github.com/jinpikaFE/go_fiber/pkg/setting"
)

func main() {
  app := fiber.New()

  app.Get("/", func(c *fiber.Ctx) error {
    return c.SendString("Hello, World!")
  })

  app.Listen(fmt.Sprintf(":%d", setting.HTTPPort))
}

当前目录结构

go-fiber/
├── conf
│   - app.ini
├── pkg
│   └── setting
│       └── setting.go
│ - main.go

启动项目

go run main.go

打开 http://127.0.0.1:9999 可以看到 Hello, World!

二、路由配置

新建routers文件夹,创建router.go

package routers

import (
	"github.com/gofiber/fiber/v2"
	controller "github.com/jinpikaFE/go_fiber/controllers"
)

func InitRouter() *fiber.App {
	app := fiber.New()

	apiv1 := app.Group("/v1")

	{
		apiv1.Get("/test", controller.GetTests)
	}

	return app
}

创建controllers文件夹,创建test.go

package controller

import "github.com/gofiber/fiber/v2"

// 获取Test列表
func GetTests(c *fiber.Ctx) error {

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"message": "test",
	})
}

修改main.go

package main

import (
	"fmt"

	"github.com/jinpikaFE/go_fiber/pkg/setting"
	"github.com/jinpikaFE/go_fiber/routers"
)

func main() {
	app := routers.InitRouter()

	app.Listen(fmt.Sprintf(":%d", setting.HTTPPort))
}

重启项目

使用postman 或者 打开 http://localhost:9999/v1/test

可以看到如下数据结构

{
    "message": "test"
}

当前目录结构

go-fiber/
├── conf
│   - app.ini
├── controllers
│   - test.go
├── pkg
│   └── setting
│       └── setting.go
├── routers
│   - router.go
│ - main.go

三、使用gorm操作mysql数据库

拉取gorm的依赖包

go get -u github.com/jinzhu/gorm

拉取mysql驱动的依赖包

go get -u github.com/go-sql-driver/mysql

创建test表

CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT '' COMMENT '名称',
  `created_on` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
  `modified_on` int(10) unsigned DEFAULT '0' COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

新建models文件夹 新建model.go

package models

import (
	"fmt"
	"log"

	"github.com/jinpikaFE/go_fiber/pkg/setting"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

var db *gorm.DB

// 所有表都统一加入下面三个字段
type Model struct {
	ID int `gorm:"primary_key" json:"id"`
	CreatedOn int `json:"created_on"`
	ModifiedOn int `json:"modified_on"`
}

func init() {
	var (
		err error
		dbType, dbName, user, password, host string
	)

	sec, err := setting.Cfg.GetSection("database")
	if err != nil {
		log.Fatal(2, "Fail to get section 'database': %v", err)
	}

	dbType = sec.Key("TYPE").String()
	dbName = sec.Key("NAME").String()
	user = sec.Key("USER").String()
	password = sec.Key("PASSWORD").String()
	host = sec.Key("HOST").String()

	db, err = gorm.Open(dbType, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
		user,
		password,
		host,
		dbName))

	if err != nil {
		log.Fatal(err)
	}

	db.SingularTable(true)
	db.LogMode(true)
	db.DB().SetMaxIdleConns(10)
	db.DB().SetMaxOpenConns(100)
}

func CloseDB() {
	defer db.Close()
}

新建test.go

package models

import (
	"time"

	"github.com/jinzhu/gorm"
)

type Test struct {
	Model

	// query tag是query参数别名,json xml,form适合post
	Name string `query:"name" json:"name" xml:"name" form:"name"`
}

func GetTests(pageNum int, pageSize int, maps interface{}) (tests []Test) {
	db.Where(maps).Offset(pageNum).Limit(pageSize).Find(&tests)

	return
}

func AddTest(test *Test) bool {
	db.Create(&test)

	return true
}

func EditTest(id int, data interface{}) bool {
	db.Model(&Test{}).Where("id = ?", id).Updates(data)

	return true
}

func DeleteTest(id int) bool {
	db.Where("id = ?", id).Delete(Test{})

	return true
}

// 根据id判断test 对象是否存在
func ExistTestByID(id int) bool {
    var test Test
    db.Select("id").Where("id = ?", id).First(&test)

    return test.ID > 0
}

// gorm所支持的回调方法:

// 创建:BeforeSave、BeforeCreate、AfterCreate、AfterSave
// 更新:BeforeSave、BeforeUpdate、AfterUpdate、AfterSave
// 删除:BeforeDelete、AfterDelete
// 查询:AfterFind

func (test *Test) BeforeCreate(scope *gorm.Scope) error {
	scope.SetColumn("CreatedOn", time.Now().Unix())

	return nil
}

func (test *Test) BeforeUpdate(scope *gorm.Scope) error {
	scope.SetColumn("ModifiedOn", time.Now().Unix())

	return nil
}

修改controllers 下的test.go

package controller

import (
	"log"
	"strconv"

	"github.com/gofiber/fiber/v2"
	"github.com/jinpikaFE/go_fiber/models"
)

// var (
// 	me
// )

// 获取Test列表
func GetTests(c *fiber.Ctx) error {
	// maps := make(map[string]interface{})
	// // 获取get query参数 或者使用queryparser
	// id := c.Query("id")
	// maps["id"] = id

	maps := &models.Test{}
	c.QueryParser(maps)

	res := models.GetTests(0, 10, maps)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"code":    200,
		"message": "SUCCESS",
		"data":    res,
		"query":   maps,
	})
}

// 添加test
func AddTest(c *fiber.Ctx) error {
	test := &models.Test{}
	c.BodyParser(test)

	res := models.AddTest(test)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"code":    200,
		"message": "SUCCESS",
		"data":    res,
	})
}

// 编辑test
func EditTest(c *fiber.Ctx) error {
	id, err := strconv.Atoi(c.Params("id"))
	test := &models.Test{}
	c.BodyParser(test)
	code := 200
	res := false
	message := "SUCCESS"

	if err != nil {
		log.Fatal(err)
	}
	if models.ExistTestByID(id) {
		res = models.EditTest(id, test)
	} else {
		code = 500
	}

	if res {
		message = "SUCCESS"
	} else {
		message = "ERROR"
	}

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"code":    code,
		"message": message,
		"data":    res,
	})
}

// 删除test
func DelTest(c *fiber.Ctx) error {
	id, err := strconv.Atoi(c.Params("id"))
	code := 200
	res := false
	message := "SUCCESS"

	if err != nil {
		log.Fatal(err)
	}

	if models.ExistTestByID(id) {
		res = models.DeleteTest(id)
	} else {
		code = 500
	}

	if res {
		message = "SUCCESS"
	} else {
		message = "ERROR"
	}


	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"code":    code,
		"message": message,
		"data":    res,
	})
}

修改routers 的router.go

package routers

import (
	"github.com/gofiber/fiber/v2"
	controller "github.com/jinpikaFE/go_fiber/controllers"
)

func InitRouter() *fiber.App {
	app := fiber.New()

	apiv1 := app.Group("/v1")

	{
		apiv1.Get("/test", controller.GetTests)
		apiv1.Post("/test", controller.AddTest)
		apiv1.Put("/test/:id", controller.EditTest)
		apiv1.Delete("/test/:id", controller.DelTest)
	}

	return app
}

当前目录结构

go-fiber/
├── conf
│   - app.ini
├── controllers
│   - test.go
├── models
│   - model.go
│   - test.go
├── pkg
│   └── setting
│       └── setting.go
├── routers
│   - router.go
│ - main.go

go run main.go 重启应用

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值