go + gin + xorm + viper 搭建模板化curd
项目
config 配置中心
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
| func init() { viper.SetConfigName("db-test") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.SetDefault("data", "data") }
func Load() error { return viper.ReadInConfig() } func Store() error { return viper.SafeWriteConfig() }
func Register(module string, key string, value any) { viper.SetDefault(module+"."+key, value) } func GetString(module string, key string) string { return viper.GetString(module + "." + key) }
func GetBool(module string, key string) bool { return viper.GetBool(module + "." + key) } func GetInt(module string, key string) int { return viper.GetInt(module + "." + key) }
|
db
初始化配置
1 2 3 4 5 6 7 8 9
| const MODULE = "database"
func init() { config.Register(MODULE, "type", "mysql") config.Register(MODULE, "url", "root:test@tcp(test:3306)/master?charset=utf8") config.Register(MODULE, "debug", false) config.Register(MODULE, "sync", true) }
|
创建engine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var Engine *xorm.Engine
func Open() error { var err error Engine, err = xorm.NewEngine(config.GetString(MODULE, "type"), config.GetString(MODULE, "url")) if err != nil { return err } if config.GetBool(MODULE, "debug") { Engine.ShowSQL(true) Engine.SetLogLevel(log.LOG_DEBUG) } if config.GetBool(MODULE, "sync") { Engine.Sync2() } return nil } func Close() error { return Engine.Close() }
|
models
收集全部模型 用于初始化数据库
1 2 3 4 5 6
| var models []any
func Register(m ...any) { models = append(models, m...) }
|
types
init
1 2 3 4 5
| 注册全部的模型 用于同步数据库 func init() { db.Register(new(User), new(Password)) }
|
新建模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| type User struct { Id string `json:"id" xorm:"pk"` Name string `json:"name,omitempty"` Email string `json:"email,omitempty"` CellPhone string `json:"cellPhone,omitempty"` Admin bool `json:"admin,omitempty"` Disable bool `json:"disable,omitempty"` Create time.Time `json:"create,omitempty" xorm:"created"` }
type Password struct { Id string `json:"id" xorm:"pk"` Password string `json:"password"` }
|
api封装
统一router注册
1 2 3 4
| func RegisterRoutes(group *gin.RouterGroup) { UserRouter(group.Group("/user")) }
|
不同模块的增删改查
走统一的curd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
func noopUserList() {} func UserRouter(app *gin.RouterGroup) { app.GET("/list", curd.AipList[types.User]()) }
|
swaggo 相关
引包
1 2
| import "github.com/swaggo/gin-swagger" import "github.com/swaggo/files"
|
安装swag
1 2
| $ go get -u github.com/swaggo/swag/cmd/swag
|
安装之后就可以通过swag init
在项目目录生成docs文件夹
在 main.go 中导入刚才生成的 docs 包
1 2 3
| import ( _ "test/docs" )
|
添加注释
1 2 3 4 5 6 7 8 9 10
|
func noopUserList() {}
|
配置文档handler
最后则是在 router 中增加 swagger 的 handler 了。
1 2 3
| engine := gin.New() engine.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
gin-gonic
初始化配置
1 2 3 4 5 6 7 8 9 10 11 12
| func init() { config.Register(MODULE, "port", 8081) config.Register(MODULE, "debug", false) config.Register(MODULE, "cors", false) config.Register(MODULE, "gzip", true) config.Register(MODULE, "https", "") config.Register(MODULE, "cert", "") config.Register(MODULE, "key", "") config.Register(MODULE, "hosts", []string{}) config.Register(MODULE, "email", "")
}
|
启动服务
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 32 33 34 35 36 37 38
| type Engine struct { *gin.Engine }
func CreateEngine() *Engine { if !config.GetBool(MODULE, "debug") { gin.SetMode(gin.ReleaseMode) }
app := gin.New() app.Use(gin.Recovery()) if config.GetBool(MODULE, "debug") { app.Use(gin.Logger()) } if config.GetBool(MODULE, "cors") { c := cors.DefaultConfig() c.AllowAllOrigins = true c.AllowCredentials = true app.Use(cors.New(c)) } app.Use(sessions.Sessions("gin-test", cookie.NewStore([]byte("gin-test")))) if config.GetBool(MODULE, "gzip") { app.Use(gzip.Gzip(gzip.DefaultCompression)) } return &Engine{app} }
func (app *Engine) Serve() { port := config.GetInt(MODULE, "port") addr := ":" + strconv.Itoa(port)
err := app.Run(addr) if err != nil { fmt.Println(err) } }
|