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   进击的davis  阅读(412)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2021-11-05 uwsgi的使用示例+django(监听队列长度)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示