golang-gin-gorm-viper实现数据简单的增删改查
目录结构:
配置文件:
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(¶ms, 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(¶ms, 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 }
程序启动及请求流程:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2021-11-05 uwsgi的使用示例+django(监听队列长度)