golang-gin-gorm-viper实现数据简单的增删改查

目录结构:
image

配置文件:

app:
  addr: 127.0.0.1:8888
mysql:
  host: 172.xx.xx.xx
  port: 3306
  user: root
  password: root
  database: gin
  enable: true
  gorm:
    skipDefaultTx: false # 是否跳过默认事务
    tablePrefix: "app_" #表前缀
    singularTable: true # 是否使用单数表名(默认复数),启用后,User结构体表将是user

main:

package main

import (
	"gin-gorm-viper/core"
	"gin-gorm-viper/initialize"
)

func main()  {
	initialize.InitConfig()
	// run server
	core.RunServer()
}

全局定义:

// server.go
package global

import (
	"gin-gorm-viper/config"
	"gorm.io/gorm"
)

const (
	ConfigPath = "./config.yaml"
)

var (
	GlobalConfig config.ServerConfig
	SqlClient *gorm.DB
)

初始化:

package initialize

import (
	"fmt"
	"gin-gorm-viper/global"
	"gin-gorm-viper/models"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

func InitConfig()  {
	// init config
	initViper()
	// init gorm
	initGorm()
}

// init config from config file
func initViper()  {
	// basic setup
	viper.SetConfigFile("yaml")
	viper.SetConfigFile(global.ConfigPath)

	// read yaml config
	err := viper.ReadInConfig()
	if err != nil {
		fmt.Println(err)
	}
	err = viper.Unmarshal(&global.GlobalConfig)
	if err != nil {
		fmt.Println(err)
	}

	// setup watch mechanism
	viper.WatchConfig()
	viper.OnConfigChange(func(in fsnotify.Event) {
		err = viper.Unmarshal(&global.GlobalConfig)
		if err != nil {
			fmt.Println(err)
		}
	})
}

// init gorm from config
func initGorm()  {
	dbConfig := global.GlobalConfig.Mysql
	gormConfig := &gorm.Config{
		SkipDefaultTransaction: dbConfig.Gorm.SkipDefaultTx,
		NamingStrategy: schema.NamingStrategy{
		//	TablePrefix: dbConfig.Gorm.TablePrefix,
		//	SingularTable: dbConfig.Gorm.SingularTable,
		},
	}
	if dbConfig.Enable { // mysql as db
		dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
			dbConfig.User,
			dbConfig.Password,
			dbConfig.Host,
			dbConfig.Port,
			dbConfig.Database)
		conn, err := gorm.Open(mysql.Open(dsn), gormConfig)
		if err != nil {
			fmt.Println("create mysql client failed.")
			return
		}
		mysqlDB, err := conn.DB()
		if err != nil {
			fmt.Println("Invalid DB.")
			return
		}
		mysqlDB.SetMaxIdleConns(10)
		mysqlDB.SetMaxOpenConns(100)
		if err = mysqlDB.Ping(); err != nil {
			fmt.Println("mysql client failed.")
		}
		fmt.Println("mysql client success.")
		global.SqlClient = conn
	} else { // default sqlite as db
		conn, err := gorm.Open(sqlite.Open("test.db"), gormConfig)
		if err != nil {
			fmt.Println("create sqlite client failed.")
			return
		}
		global.SqlClient = conn
	}

	// init create user table
	err := global.SqlClient.AutoMigrate(&models.User{})
	if err != nil {
		fmt.Println(err.Error())
	}
}

核心目录:

// server.go
package core

import (
	"gin-gorm-viper/global"
	"github.com/gin-gonic/gin"
)

func RunServer()  {
	engine := gin.Default()

	RegisterRouters(engine)


	engine.Run(global.GlobalConfig.App.Addr)
}

路由注册:

// registerRouters.go
package core

import (
	v1 "gin-gorm-viper/app/v1"
	"github.com/gin-gonic/gin"
	"net/http"
)

func RegisterRouters(e *gin.Engine)  {
	e.GET("/hello", func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 0,
			"msg": "hello gin",
		})
	})
	e.POST("/user/add", v1.Register)
	e.GET("/user/get", v1.Get)
	e.DELETE("/user/delete", v1.DeleteUser)
}

接口:

// register.go
package v1

import (
	"gin-gorm-viper/global"
	"gin-gorm-viper/models"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type Params struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

func Register(ctx *gin.Context)  {
	var params Params
	ctx.ShouldBindBodyWith(&params, binding.JSON)

	user := models.User{
		Username: params.Username,
		Password: params.Password,
	}

	ok, err := models.CreateUser(user)
	if !ok {
		ctx.JSON(200, gin.H{"msg": "register failed."})
		return
	}
	if ok && err !=nil {
		ctx.JSON(200, gin.H{"msg": err.Error()})
		return
	}
	ctx.JSON(200, gin.H{"msg": "success"})
}

func Get(ctx *gin.Context)  {
	var users []models.User
	_ = global.SqlClient.Find(&users)
	if len(users) > 0 {
		userList := make([]string, 0, len(users))
		for _, user := range users {
			userList = append(userList, user.Username)
		}
		ctx.JSON(200, gin.H{
			"msg": "success",
			"data": userList,
		})
		return
	}

	ctx.JSON(200, gin.H{
		"msg": "success",
		"data": []string{},
	})
}

func DeleteUser(ctx *gin.Context)  {
	var params Params
	ctx.ShouldBindBodyWith(&params, binding.JSON)
	user := models.User{
		Username: params.Username,
	}

	global.SqlClient.Where("username = ?", user.Username).Delete(&models.User{})

	ctx.JSON(200, gin.H{"msg": "delete success."})
}

模型定义-service方法:

// user.go
package models

import (
	"gin-gorm-viper/global"
	"github.com/pkg/errors"
	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Username string `json:"username" gorm:"type:varchar(20)"`
	Password string `json:"password" gorm:"type:varchar(20)"`
}

func (u User) TableName() string {
	return "user"
}


func CreateUser(user User) (bool, error) {
	tx := global.SqlClient.Select("id").Where("username = ?", user.Username).Find(&User{})
	if tx.RowsAffected > 0 {
		return true, errors.New("already registerd.")
	}

	global.SqlClient.Save(&user)
	return true, nil
}

程序启动及请求流程:

posted on 2022-11-05 17:18  进击的davis  阅读(357)  评论(0编辑  收藏  举报

导航