From 1de23a929f27aaa3f14234b5aff634ddee1fca87 Mon Sep 17 00:00:00 2001 From: yumaojun03 <719118794@qq.com> Date: Sat, 16 Nov 2024 14:57:48 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 9 ++++- go.sum | 11 ++++++ skills/gin/README.md | 79 ++++++++++++++++++++++++++++++++++++- skills/gin/main.go | 94 +++++++++++++++++++++++++++++--------------- 4 files changed, 159 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index a39b32b..ed3e04d 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,11 @@ module gitlab.com/go-course-project/go17 go 1.22.0 -require github.com/gin-gonic/gin v1.10.0 +require ( + github.com/gin-gonic/gin v1.10.0 + gorm.io/driver/mysql v1.5.7 + gorm.io/gorm v1.25.12 +) require ( github.com/bytedance/sonic v1.11.6 // indirect @@ -14,7 +18,10 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect diff --git a/go.sum b/go.sum index 7f08abb..3cabf6b 100644 --- a/go.sum +++ b/go.sum @@ -23,11 +23,17 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -85,5 +91,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= +gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/skills/gin/README.md b/skills/gin/README.md index 425d26b..5dd8fdc 100644 --- a/skills/gin/README.md +++ b/skills/gin/README.md @@ -1,3 +1,80 @@ # Gin 框架使用 -+ [官方文档](https://gin-gonic.com/zh-cn/docs/) \ No newline at end of file ++ [官方文档](https://gin-gonic.com/zh-cn/docs/) + + +```go +package main + +import ( + "log" + "net/http" + + "github.com/gin-gonic/gin" +) + +func main() { + // gin Engine, 它包装了http server + server := gin.Default() + + // 配置业务路有 + server.GET("/hello", func(ctx *gin.Context) { + // url query ?name=test + // header authentiaction: bearer token + // body + // 1. 读取URL路径参数: /hello/:name + // ctx: http Request/Respose, /hello/tony + // name := ctx.Param("name") + // 2. 从URL ? query string 读取用户的参数 + // /books?page_size=10&page_number=20 + // ps := ctx.Query("page_size") + // pn := ctx.Query("page_number") + // 3. 从Header中读取用户参数 + // 典型场景: 接口认证 + // Authenticaton: Bearer xxxxxxx + // ctx.GetHeader("Authenticaton") + // ctx.Request.Header.Get("Authenticaton") + // 4. 从body中读取参数 + // 用于数据的创建,往数据库里添加一条数据,比如 Create Book + // {"name": "Go语言项目", "author": "老喻"} + // JSON ----> Struct{} + book := new(Book) + + // body, _ := io.ReadAll(ctx.Request.Body) + // defer ctx.Request.Body.Close() + // if string(body) == "" { + // ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "请传达JSON格式的参数"}) + // return + // } + // json.Unmarshal(body, book) + // if err := ctx.BindJSON(book); err != nil { + // ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "msg": err.Error()}) + // return + // } + + // 业务出来 + // db.save(db) + + // json.Marshal(book) + ctx.JSON(http.StatusOK, book) + }) + + if err := server.Run("127.0.0.1:8080"); err != nil { + log.Println(err) + } +} + +type Book struct { + Name string `json:"name"` + Author string `json:"author"` +} +``` + + +```sh +[GIN-debug] POST /api/books --> main.main.func1 (3 handlers) +[GIN-debug] GET /api/books --> main.main.func2 (3 handlers) +[GIN-debug] GET /api/books/:isbn --> main.main.func3 (3 handlers) +[GIN-debug] PUT /api/books/:isbn --> main.main.func4 (3 handlers) +[GIN-debug] DELETE /api/books/:isbn --> main.main.func5 (3 handlers) +``` \ No newline at end of file diff --git a/skills/gin/main.go b/skills/gin/main.go index ee32690..2a5a6b3 100644 --- a/skills/gin/main.go +++ b/skills/gin/main.go @@ -5,45 +5,66 @@ import ( "net/http" "github.com/gin-gonic/gin" + "gorm.io/driver/mysql" + "gorm.io/gorm" ) +// 初始化数据库, 能过与数据库交互的 连接池对象: db +func setupDatabase() *gorm.DB { + dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local" + db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + panic("failed to connect database") + } + db.AutoMigrate(&Book{}) // 自动迁移 + return db +} + +// 规定好风格: JSON Restful Api func main() { // gin Engine, 它包装了http server server := gin.Default() - // 配置业务路有 - server.GET("/hello/:name", func(ctx *gin.Context) { - // url query ?name=test - // header authentiaction: bearer token - // body - // 1. 读取URL路径参数 - // ctx: http Request/Respose, /hello/tony - // name := ctx.Param("name") - // 2. 从URL ? query string 读取用户的参数 - // /books?page_size=10&page_number=20 - // ps := ctx.Query("page_size") - // pn := ctx.Query("page_number") - // 3. 从Header中读取用户参数 - // 典型场景: 接口认证 - // Authenticaton: Bearer xxxxxxx - // ctx.GetHeader("Authenticaton") - // ctx.Request.Header.Get("Authenticaton") - // 4. 从body中读取参数 - // 用于数据的创建,往数据库里添加一条数据,比如 Create Book - // {"name": "Go语言项目", "author": "老喻"} - // JSON ----> Struct{} - book := new(Book) - - // body, _ := io.ReadAll(ctx.Request.Body) - // defer ctx.Request.Body.Close() - // json.Unmarshal(body, book) - if err := ctx.ShouldBindJSON(book); err != nil { - ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "msg": err}) + db := setupDatabase() + // 配置业务路有, Book类型的资源的 一套简单的CRUD + // 创建Book -> Book + // POST, Body + book := server.Group("/api/books") + book.POST("", func(ctx *gin.Context) { + // 获取Book用户传达的参数 + ins := new(Book) + if err := ctx.ShouldBindJSON(ins); err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "msg": err.Error()}) return } - // json.Marshal(book) - ctx.JSON(http.StatusOK, book) + // book, save + if err := db.Save(ins).Error; err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "msg": err.Error()}) + return + } + + ctx.JSON(http.StatusOK, ins) + }) + + // 查询Book列表 -> []*Book + book.GET("", func(ctx *gin.Context) { + + }) + + // 查询Book详情 + book.GET("/:isbn", func(ctx *gin.Context) { + + }) + + // 更新Book + book.PUT("/:isbn", func(ctx *gin.Context) { + + }) + + // 删除Book + book.DELETE("/:isbn", func(ctx *gin.Context) { + }) if err := server.Run("127.0.0.1:8080"); err != nil { @@ -51,7 +72,16 @@ func main() { } } +// Book 结构体定义 type Book struct { - Name string `json:"name"` - Author string `json:"author"` + // grom:"column:isbn;", 具体文档: https://gorm.io/docs/models.html#Fields-Tags + IsBN uint `json:"isbn" gorm:"primaryKey;column:isbn"` + Title string `json:"title" gorm:"column:title;type:varchar(200)"` + Author string `json:"author" gorm:"column:author;type:varchar(200);index"` + Price float64 `json:"price" gorm:"column:price"` +} + +// 定义该对象映射到数据里 表的名称 +func (t *Book) TableName() string { + return "books" }