GoWeb从无到有 – 读取配置文件、gin、gorm
创建go项目,结构如下
1. golang读取配置文件
-
引入包
go get -u gopkg.in/ini.v1
-
在main.go的同级目录创建config文件夹,在文件夹中创建配置文件 config.ini
# 项目配置 [app] Port=8010 # mysql配置 [mysql] Url=username:password@tcp(xxx.xxx.xxx.xxx:3306)/scanner-web?charset=utf8mb4&parseTime=True&loc=Local
-
新建model包,在model包中创建Config结构体
package model type Config struct { Port string MysqlUrl string }
-
新建common文件夹,在文件夹下创建config包,在config包中读取配置文件参数
package config import ( "gopkg.in/ini.v1" "log" "yy-data-processing/model" ) var Cfg *ini.File var Config model.Config func init() { var err error Cfg, err = ini.Load("config/config.ini") if err != nil { log.Fatalf("Fail to parse 'config.ini': %v", err) } loadApp() loadMysql() } func loadApp() { Config.Port = Cfg.Section("app").Key("Port").String() } func loadMysql() { Config.MysqlUrl = Cfg.Section("mysql").Key("Url").String() }
2. 整合gin
-
引入包
go get -u github.com/gin-gonic/gin
-
初始化路由
在根目录创建router包,创建initRouters.go
package router import "github.com/gin-gonic/gin" var routersNoCheck = make([]func(v1 *gin.RouterGroup), 0) // 初始化所有的路由 func InitRouters() *gin.Engine { r := gin.Default() // 无需认证的路由 noCheck(r) // 其他类型的路由... return r } func noCheck(r *gin.Engine) { v1 := r.Group("/api/v1") for _, f := range routersNoCheck { f(v1) } }
-
启动服务
在main.go中启动服务
package main import ( "yy-data-processing/common/config" "yy-data-processing/router" ) func main() { port := config.Config.Port routers := router.InitRouters() if err := routers.Run(":" + port); err != nil { log.Fatalf("启动服务失败") } }
3. 整合gorm (使用v2版本)
-
引入包
go get gorm.io/gorm go get gorm.io/driver/mysql
-
在common目录下新建database包,创建mysql.go
package database
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"log"
"yy-data-processing/common/config"
)
// 定义db全局变量
var Db *gorm.DB
func InitMysql() *gorm.DB {
var err error
url := config.Config.MysqlUrl
Db, err = gorm.Open(mysql.Open(url), &gorm.Config{
SkipDefaultTransaction: true,
AllowGlobalUpdate: true,
PrepareStmt: true,
NamingStrategy: schema.NamingStrategy{
// 禁用后缀加s,结构体对应的表名不用带s
SingularTable: true,
},
})
if err != nil {
log.Printf("Connecting database failed: ", err)
panic(err)
}
if Db != nil {
log.Println("MySql连接成功")
}
db, err := Db.DB()
// 设置连接池
db.SetMaxIdleConns(5)
// 最大连接数
db.SetMaxOpenConns(10)
return Db
}
-
main方法中初始化数据库
package main import ( "log" "yy-data-processing/common/config" "yy-data-processing/common/database" "yy-data-processing/router" ) func main() { // 初始化路由 routers := router.InitRouters() // 初始化mysql db := database.InitMysql() if db != nil { log.Println("db连接成功") } defer db.Close() port := config.Config.Port if err := routers.Run(":" + port); err != nil { log.Fatalf("启动服务失败: ", err) } }
4. 编写api测试
-
在model包下新建user.go
package model type User struct { Id int `json:"id"` Name string `json:"name"` Age int `json:"age"` }
-
新建router目录,创建userRouter.go
package router import ( "github.com/gin-gonic/gin" "yy-data-processing/apis" ) func init() { routersNoCheck = append(routersNoCheck, registerUserRouter) } func registerUserRouter(v1 *gin.RouterGroup) { apis := apis.UserApis{} r := v1.Group("/user") { r.POST("/createUser", apis.SaveUser) r.GET("/findUser", apis.FindUser) } }
-
新建apis目录,创建userApis.go
package apis import ( "github.com/gin-gonic/gin" "net/http" "yy-data-processing/model" "yy-data-processing/service" ) type UserApis struct { } func (u *UserApis) SaveUser(c *gin.Context) { user := model.User{} user.Name = "user1" user.Age = 20 s := service.UserService{} err := s.SaveUser(user) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "msg": "新增数据失败", "error": err, }) return } c.JSON(http.StatusOK, gin.H{ "msg": "新增数据成功", }) } func (u *UserApis) FindUser(c *gin.Context) { s := service.UserService{} user := s.FindUser(6) c.JSON(http.StatusOK, gin.H{ "msg": "查询数据成功", "data": user, }) }
-
新建service目录,创建userService.go
package service import ( "yy-data-processing/common/database" "yy-data-processing/model" ) type UserService struct { } // upsert操作 func (s *UserService) SaveUser(user model.User) error { dbResp := database.Db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{"name", "age"}), }).Create(&user) if dbResp.Error != nil { return dbResp.Error } return nil } func (s *UserService) FindUser(id int) model.User { user := model.User{} database.Db.Where("id = ?", id).Find(&user) return user }
-
访问api测试