前言

一直想自己搭建属于自己的个人的web博客,以此来记录一下过程。

初始化项目

可以在gitee或者github建一个仓库,然后初始化项目到本地即可。

  1. gin框架项目结构,我大体分为了这几个部分
  • api是逻辑代码,都会放到这里
  • config是配置文件
  • middleware:中间件
  • model:orm模型
  • routes:路由
  • upload:上传的静态文件,后期会改成线上或者自己搭建的静态服务器
  • utils:工具,一些通用的代码会放在这里
  • web:前端项目

定义好自己的项目结构,然后新建一个main.go。

包管理工具,我使用的是mod。

go mod init 项目名
  1. 然后安装gin框架,请观看这篇文章

  2. 配置文件,使用的是ini文件,官网地址在这里,命令为

    go get gopkg.in/ini.v1
  3. config下新建config.ini文件,定义自己的服务端口和数据库信息

    [server]
    # 默认为debug模式,生产使用release模式
    AppMode = debug
    HttpPort = :8020
    
    [database]
    Db = mysql
    DbHost = 127.0.0.1
    DbPort = 3306
    DbUser = root
    DbPassWord = root
    DbName = blogdb
  4. 在utils下新建settings.go,来引入ini配置

    import (
    	"fmt"
    	"gopkg.in/ini.v1"
    )
    
    var (
    	AppMode string
    	HttpPort string
    
    	Db         string
    	DbHost     string
    	DbPort     string
    	DbUser     string
    	DbPassWord string
    	DbName     string
    )
    
    // 初始化的函数
    func init() {
    	file, err := ini.Load("config/config.ini")
    	if err != nil {
    		fmt.Println("配置文件读取错误,请检查路径", err)
      }
    
    	LoadServer(file)
    	LoadData(file)
    }
    
    // 服务端配置
    func LoadServer(file *ini.File) {
    	AppMode = file.Section("server").Key("AppMode").MustString("debug")
    	HttpPort = file.Section("server").Key("HttpPort").MustString(":8020")
    }
    
    // 数据库配置
    func LoadData(file *ini.File) {
    	Db = file.Section("database").Key("Db").MustString("debug")
    	DbHost = file.Section("database").Key("DbHost").MustString("localhost")
    	DbPort = file.Section("database").Key("DbPort").MustString("3306")
    	DbUser = file.Section("database").Key("DbUser").MustString("root")
    	DbPassWord = file.Section("database").Key("DbPassWord").MustString("root")
    	DbName = file.Section("database").Key("DbName").MustString("blogdb")
    }
    
  5. 然后测试一下路由版本管理,在routes下新建router.go文件,把InitRouter函数添加到main.go下的main函数中。

    import (
    	"blog/utils"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func InitRouter()  {
    	gin.SetMode(utils.AppMode)
    	r := gin.Default()
    
    	router := r.Group("api/v1")
    	{
    		router.GET("hello/", func(c *gin.Context) {
    			c.JSON(http.StatusOK,gin.H{
    				"msg":"ok",
    			})
    		})
    	}
    
    	r.Run(utils.HttpPort)
    
    }

    启动项目,go run main.go,访问一下localhost:8020/api/v1/hello/,显示ok,成功。

ORM迁移数据库

orm我使用的是文档最为全面的GORM,在更新到了GORM2之后,和之前的版本有些许不同,为此,我也不搬砖了,地址

model下新建三个文件(User.go、Category.go、Article.go)来定义我们的模型,也就是表。

User.go:

import "gorm.io/gorm"

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20);not null " json:"username" validate:"required,min=4,max=12" label:"用户名"`
	Password string `gorm:"type:varchar(500);not null" json:"password" validate:"required,min=6,max=120" label:"密码"`
	Avatar string `gorm:"type:varchar(40);not null" json:"avatar" label:"头像"`
	Role     int    `gorm:"type:int;DEFAULT:2" json:"role" validate:"required,gte=2" label:"角色"`
}

Article.go:

package model

import "gorm.io/gorm"


type Article struct {
	Category Category `gorm:"foreignkey:Cid"`
	gorm.Model
	Title        string `gorm:"type:varchar(100);not null" json:"title"`
	Cid          int    `gorm:"type:int;not null" json:"cid"`
	Desc         string `gorm:"type:varchar(200)" json:"desc"`
	Content      string `gorm:"type:longtext" json:"content"`
	Img          string `gorm:"type:varchar(100)" json:"img"`
}

Category.go:

package model

type Category struct {
	ID   uint   `gorm:"primary_key;auto_increment" json:"id"`
	Name string `gorm:"type:varchar(20);not null" json:"name"`
}

然后再新建一个db.go来进行配置

var db *gorm.DB
var err error


func InitDb()  {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		utils.DbUser,
		utils.DbPassWord,
		utils.DbHost,
		utils.DbPort,
		utils.DbName,
	)

	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		// gorm日志模式:silent
		Logger: logger.Default.LogMode(logger.Silent),
		// 外键约束
		DisableForeignKeyConstraintWhenMigrating: true,
		// 禁用默认事务(提高运行速度)
		SkipDefaultTransaction: true,
		NamingStrategy: schema.NamingStrategy{
			// 使用单数表名,启用该选项,此时,`User` 的表名应该是 `user`
			SingularTable: true,
		},
	})

	if err != nil{
		fmt.Println("链接数据库失败。", err)
	}
	// 迁移数据表,在没有数据表结构变更时候,建议注释不执行
	_ = db.AutoMigrate(&User{}, &Article{}, &Category{})

	sqlDB, _ := db.DB()
	// SetMaxIdleCons 设置连接池中的最大闲置连接数。
	sqlDB.SetMaxIdleConns(10)

	// SetMaxOpenCons 设置数据库的最大连接数量。
	sqlDB.SetMaxOpenConns(100)

	// SetConnMaxLifetiment 设置连接的最大可复用时间。
	sqlDB.SetConnMaxLifetime(10 * time.Second)

}

然后把初始化函数配置到main.go中。

package main

import (
	"blog/model"
	"blog/routes"
)

func main()  {
	model.InitDb()
	routes.InitRouter()
}

然后启动项目,他就会自动的进行迁移,如果你们跟我一样,项目启动了,他没有迁移,那就,*@¥&@¥的,自己建吧,这个GORM我也没有理解的太好,哪怕代码正常运行,他也没有迁移表。

最后,目前的项目结构是这样。

未完待续….