go:generate
//go:generate go env -w GO111MODULE=on
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
//go:generate go mod tidy
Viper 读写配置文件
v := viper.New() v.SetConfigFile("config.yaml") v.SetConfigType("yaml") err := v.ReadInConfig() if err != nil { panic(fmt.Errorf("Fatal error config file: %s \n", err)) } if err = v.Unmarshal(&global.GVA_CONFIG); err != nil { fmt.Println(err) } cs := utils.StructToMap(global.GVA_CONFIG) for k, v2 := range cs { v.Set(k, v2) } v.WriteConfig()
ZAP 保存日志
global.GVA_LOG.Error(“获取失败!”, zap.Error(errors.New(“====”)))
global.GVA_LOG.Info("server run success on ", zap.String(“address”, address))
定时任务
tm := timer.NewTimerTask() _, err := tm.AddTaskByFunc("func", "@every 1s", mockFunc) if err == nil { tm.StartTask("func") println("StartTask=func") }
创建api
model
api 需要调用的api
router 路由
service 业务代码
model->service->api->router-initRouter
model
type Userinfo struct { Name string `uri:"name" form:"name" json:"name"` Pwd string `uri:"pwd" form:"pwd" json:"pwd"` } type UserinfoResponse struct { Userinfo example.Userinfo `json:"userinfo"` Token string `json:"token"` }
步骤 1. 创建service
- example/exa_api.go
type ExaApiService struct { } var ExaApiServiceApp = new(ExaApiService) func (exaApi *ExaApiService) Login(u example.Userinfo) string { return fmt.Sprintf("Login2=name=%s password=%s", u.Name, u.Pwd) } func (exaApi *ExaApiService) GetUserInfo(u example.Userinfo) string { return fmt.Sprintf("GetUserInfo2=name=%s password=%s", u.Name, u.Pwd) }
- example/enter.go
type ServiceGroup struct { ExaApiService }
- enter.go
type ServiceGroup struct { ExaServiceGroup example.ServiceGroup } var ServiceGroupApp = new(ServiceGroup)
步骤 2. 创建api
- example/enter.go
type ApiGroup struct { ExaApi } var ( exaService = service.ServiceGroupApp.ExaServiceGroup.ExaApiService )
- example/exa_api.go
package example import ( "github.com/gin-gonic/gin" "github.com/githubuityu/study_gin_admin/model/common/response" "github.com/githubuityu/study_gin_admin/model/example" ) type ExaApi struct { } // Login /* // http://127.0.0.1:8888/exaApi/login // application/x-www-form-urlencoded或者form-data func (e *ExaApi) Login(c *gin.Context) { var userinfo example.Userinfo err := c.ShouldBind(&userinfo) if err != nil { response.FailWithMessage(err.Error(), c) return } response.OkWithMessage(exaService.Login(userinfo), c) } // http://127.0.0.1:8888/exaApi/getUserInfo?name=zhangsan&pwd=6666 func (e *ExaApi) GetUserInfo(c *gin.Context) { var userinfo example.Userinfo err := c.ShouldBind(&userinfo) if err != nil { response.FailWithMessage(err.Error(), c) return } response.OkWithMessage(exaService.GetUserInfo(userinfo), c) } // http://127.0.0.1:8888/exaApi/login // // raw { // "name":"zhangsan", // "pwd":"23333" // } func (e *ExaApi) LoginJson(c *gin.Context) { var userinfo example.Userinfo err := c.ShouldBindJSON(&userinfo) if err != nil { response.FailWithMessage(err.Error(), c) return } response.OkWithMessage(exaService.Login(userinfo), c) } // http://127.0.0.1:8888/exaApi/getUserInfoPath/zhangsan/555 func (e *ExaApi) GetUserInfoPath(c *gin.Context) { var userinfo example.Userinfo err := c.ShouldBindUri(&userinfo) if err != nil { response.FailWithMessage(err.Error(), c) return } response.OkWithMessage(exaService.GetUserInfo(userinfo), c) }
- enter.go
type ApiGroup struct { ExaApiGroup example.ApiGroup } var ApiGroupApp = new(ApiGroup)
步骤 3. 创建router
- example/exa_api.go
type ExaRouter struct { } func (e *ExaRouter) InitExaAPiRouter(Router *gin.RouterGroup) { exaApiRouter := Router.Group("exaApi").Use(middleware.ExaMiddleware()) exaApiRouterWithoutRecord := Router.Group("exaApi") exaApi := v1.ApiGroupApp.ExaApiGroup { exaApiRouter.POST("login", exaApi.Login) exaApiRouter.POST("loginJson", exaApi.LoginJson) } { exaApiRouterWithoutRecord.GET("getUserInfo", exaApi.GetUserInfo) exaApiRouterWithoutRecord.GET("getUserInfoPath/:name/:pwd", exaApi.GetUserInfoPath) } }
- example/enter.go
type RouterGroup struct { ExaRouter }
- enter.go
type RouterGroup struct { Example example.RouterGroup } var RouterGroupApp = new(RouterGroup)
初始化总路由
func Routers() *gin.Engine { // 设置为发布模式 if global.GVA_CONFIG.System.Env == "public" { gin.SetMode(gin.ReleaseMode) //DebugMode ReleaseMode TestMode } Router := gin.New() exaApiRouter := router.RouterGroupApp.Example //PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) { // 健康监测 PublicGroup.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, "ok") }) } exaApiRouter.InitExaAPiRouter(PublicGroup) global.GVA_LOG.Info("router register success") return Router }
启动
package main import ( "fmt" "github.com/githubuityu/study_gin_admin/core" "github.com/githubuityu/study_gin_admin/global" "github.com/githubuityu/study_gin_admin/initialize" "go.uber.org/zap" "time" ) //go:generate go env -w GO111MODULE=on //go:generate go env -w GOPROXY=https://goproxy.cn,direct //go:generate go mod tidy //go:generate go mod download func main() { global.GVA_VP = core.Viper() // 初始化Viper initialize.OtherInit() global.GVA_LOG = core.Zap() // 初始化zap日志库 zap.ReplaceGlobals(global.GVA_LOG) global.GVA_DB = initialize.Gorm() // gorm连接数据库 initialize.Timer() core.RunWindowsServer() }
go-swagger
参数类型 query、path、body、header,formData
参数参数类型 string integer number boolean struct
// Login // @Summary 用户登录 // @Tags ExaApi // @Produce application/json // @Param name formData string false "名字" // @Param pwd formData string false "密码" // @Success 200 {object} response.Response{data=exaApiRes.UserinfoResponse,msg=string} "返回包括用户信息,token,过期时间" // @Router /exaApi/login [post] func (e *ExaApi) Login(c *gin.Context) { var userinfo example.Userinfo err := c.ShouldBind(&userinfo) if err != nil { response.FailWithMessage(err.Error(), c) return } response.OkWithDetailed(exaApiRes.UserinfoResponse{ Userinfo: userinfo, Token: userinfo.Pwd, }, "登录成功", c) }
路由配置
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
swag init
test
- 创建一个a.go
- 创建一个测试文件a_test.go
- 创建一个方法方法名以Test开始,参数为(t *testing.T)
//a.go package utils type TestA struct { TestB } type TestB struct { } func (tb *TestB) GetInfo() string { return "返回数据" } var ItyuTestA = new(TestA) package utils //a_test.go import "testing" func TestAaaa(t *testing.T) { print(ItyuTestA.TestB.GetInfo()) }
将嵌套结构定义为指针或对象利弊
- 将嵌套结构定义为指针:
内存效率:使用指针可以提高内存效率,特别是当嵌套结构体很大时。指针只存储结构体的内存地址,而不是复制整个
结构体的数据。
可变性:如果你需要修改父结构中的嵌套结构的数据,使用指针允许你直接修改被引用的对象。
避免nil值:如果嵌套结构可能有nil值,使用指针可以通过将指针设置为nil来表示值的缺失。
- 将嵌套结构定义为对象:
简单性:直接使用对象可以简化代码,因为不需要处理指针解引用。它可以使代码更易于阅读和理解。
避免与指针相关的问题:操作指针需要小心处理,以避免空指针异常和内存泄漏。使用对象可以帮助避免此类问题。
不可变性:如果嵌套结构的数据在父结构中应该被视为不可变的,那么使用对象可以强制这种不可变性并防止无意的修
改。
- 最终,对嵌套结构使用指针还是对象的选择取决于性能、可变性要求、内存使用和代码简单性等因素。考虑应用程序的具体需求,并根据这些需求做出决定。
结构体嵌套
结构体嵌套在编程中有多种作用和用途,以下是一些常见的用途:
- 组合数据:结构体嵌套允许将多个相关的数据字段组合在一起,形成更复杂的数据结构。通过嵌套其他结构体,可以在一个结构体中包含其他结构体的数据,从而形成逻辑上的组合关系。
- 嵌套层次:通过结构体嵌套,可以创建多层次的数据结构,形成树状或层次化的关系。这样可以更好地组织和管理数据,使其更具可读性和可维护性。
- 代码复用:结构体嵌套可以实现代码的复用。通过将一个结构体嵌套到另一个结构体中,可以共享嵌套结构体的字段和方法,避免重复定义和编写相同的代码。
- 组合功能:通过将一个结构体嵌套到另一个结构体中,可以将嵌套结构体的方法和行为组合到外部结构体中,形成更丰富的功能。外部结构体可以调用嵌套结构体的方法,实现更复杂的行为。
- 数据模型:结构体嵌套可以用于定义和表示复杂的数据模型。通过将多个相关的数据结构嵌套在一起,可以更好地表示现实世界的实体和关系。
- 总的来说,结构体嵌套提供了一种组合和组织数据的机制,可以使代码更具可读性、可维护性和复用性。它是构建复杂数据结构和实现代码组合的重要工具之一。