Go 小清单

2024-07-31 16:16:37 浏览数 (1)

Go 小清单

今天试着复现了一下七米大佬的小清单项目,这里把主要总结一下代码逻辑。

这个项目超级简单,前端代码是已经做好的,直接去大佬仓库clone就行,只不过教程比较久远了,所以代码需要一些调整。

文件结构

代码语言:javascript复制
 D:.
 │  go.mod
 │  go.sum
 │  main.go
 │
 ├─.idea
 │      .gitignore
 │      modules.xml
 │      wait.iml
 │      workspace.xml
 │
 ├─static
 │  ├─css
 │  │      app.8eeeaf31.css
 │  │      chunk-vendors.57db8905.css
 │  │
 │  ├─fonts
 │  │      element-icons.535877f5.woff
 │  │      element-icons.732389de.ttf
 │  │
 │  └─js
 │          app.007f9690.js
 │          chunk-vendors.ddcb6f91.js
 │
 └─template
         favicon.ico
         index.html
 ​

完整代码

代码语言:javascript复制
 package main
 ​
 import (
     "github.com/gin-gonic/gin"
     "gorm.io/driver/mysql"
     "gorm.io/gorm"
     "net/http"
 )
 ​
 var db *gorm.DB
 ​
 // Todo model1
 type Todo struct {
     ID     int    `json:"id" gorm:"primaryKey;autoIncrement"`
     Title  string `json:"title"`
     Status bool   `json:"status"`
 }
 ​
 func initmysql() {
     dsn := "root:root@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
     var err error
     db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
     if err != nil {
         panic("failed to connect to database: "   err.Error())
     }
     err = db.AutoMigrate(&Todo{})
     if err != nil {
         panic("failed to migrate database: "   err.Error())
     }
 }
 ​
 func main() {
     // 连接数据库并绑定模型
     initmysql()
 ​
     r := gin.Default()
     // 告诉gin框架模板文件引用的静态文件位置
     r.Static("/static", "./static")
 ​
     // 告诉gin框架模板文件的位置
     r.LoadHTMLGlob("template/*")
 ​
     r.GET("/", func(c *gin.Context) {
         c.HTML(http.StatusOK, "index.html", nil)
     })
 ​
     v1Group := r.Group("v1")
     {
         // 添加代办事项
         v1Group.POST("/todo", func(c *gin.Context) {
             var todo Todo
             if err := c.ShouldBindJSON(&todo); err != nil {
                 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                 return
             }
             db.Create(&todo)
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 查看特定待办事项
         v1Group.GET("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             var todo Todo
             if err := db.First(&todo, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 查看所有代办事项
         v1Group.GET("/todo", func(c *gin.Context) {
             var todos []Todo
             db.Find(&todos)
             c.JSON(http.StatusOK, todos)
         })
 ​
         // 修改代办事项
         v1Group.PUT("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             var todo Todo
             if err := db.First(&todo, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             if err := c.ShouldBindJSON(&todo); err != nil {
                 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                 return
             }
             db.Save(&todo)
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 删除代办事项
         v1Group.DELETE("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             if err := db.Delete(&Todo{}, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             c.JSON(http.StatusOK, gin.H{"message": "Todo deleted"})
         })
     }
 ​
     r.Run()
 }
 ​

全局变量

代码语言:javascript复制
 var db *gorm.DB

声明一个全局变量 db,类型是 *gorm.DB,用于数据库操作。

Todo 模型

代码语言:javascript复制
 type Todo struct {
     ID     int    `json:"id" gorm:"primaryKey;autoIncrement"`
     Title  string `json:"title"`
     Status bool   `json:"status"`
 }

定义一个 Todo 结构体,用于表示代办事项。包含以下字段:

  • ID:主键,自增。
  • Title:代办事项的标题。
  • Status:代办事项的状态,表示是否完成。

初始化 MySQL 数据库

代码语言:javascript复制
 func initmysql() {
     dsn := "root:root@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
     var err error
     db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
     if err != nil {
         panic("failed to connect to database: "   err.Error())
     }
     err = db.AutoMigrate(&Todo{})
     if err != nil {
         panic("failed to migrate database: "   err.Error())
     }
 }
  1. dsn:定义数据库连接字符串,包括用户名、密码、数据库地址、数据库名称和其他参数。
  2. gorm.Open:使用 GORM 连接到 MySQL 数据库。
  3. panic:如果连接数据库失败,程序会抛出一个错误并终止运行。
  4. db.AutoMigrate:自动迁移数据库表结构,确保 Todo 结构体对应的表存在。(数据库中没有对应表的话会新建一个)

主函数

代码语言:javascript复制
 func main() {
     // 连接数据库并绑定模型
     initmysql()
 ​
     r := gin.Default()
     
     // 告诉gin框架模板文件引用的静态文件位置
     r.Static("/static", "./static")
 ​
     // 告诉gin框架模板文件的位置
     r.LoadHTMLGlob("template/*")
 ​
     r.GET("/", func(c *gin.Context) {
         c.HTML(http.StatusOK, "index.html", nil)
     })
  1. initmysql():调用函数连接数据库。
  2. gin.Default():创建一个默认的 Gin 引擎实例。
  3. r.Static:设置静态文件的路径。
  4. r.LoadHTMLGlob:设置模板文件的位置。
  5. r.GET:定义一个 GET 路由,访问根路径时返回 index.html 模板。

定义 API 路由组

代码语言:javascript复制
 v1Group := r.Group("v1")
     {
         // 添加代办事项
         v1Group.POST("/todo", func(c *gin.Context) {
             var todo Todo
             if err := c.ShouldBindJSON(&todo); err != nil {
                 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                 return
             }
             db.Create(&todo)
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 查看特定待办事项
         v1Group.GET("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             var todo Todo
             if err := db.First(&todo, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 查看所有代办事项
         v1Group.GET("/todo", func(c *gin.Context) {
             var todos []Todo
             db.Find(&todos)
             c.JSON(http.StatusOK, todos)
         })
 ​
         // 修改代办事项
         v1Group.PUT("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             var todo Todo
             if err := db.First(&todo, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             if err := c.ShouldBindJSON(&todo); err != nil {
                 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                 return
             }
             db.Save(&todo)
             c.JSON(http.StatusOK, todo)
         })
 ​
         // 删除代办事项
         v1Group.DELETE("/todo/:id", func(c *gin.Context) {
             id := c.Param("id")
             if err := db.Delete(&Todo{}, id).Error; err != nil {
                 c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
                 return
             }
             c.JSON(http.StatusOK, gin.H{"message": "Todo deleted"})
         })
     }
 ​
     r.Run()
 }
  1. r.Group("v1"):创建一个路由组 v1,用于版本控制。
  2. POST /todo:添加一个代办事项。通过 ShouldBindJSON 绑定 JSON 数据到 Todo 结构体,并保存到数据库。
  3. GET /todo/ :查看特定的代办事项。通过 URL 参数获取代办事项的 ID 并从数据库查询。
  4. GET /todo:查看所有代办事项。从数据库中获取所有 Todo 记录。
  5. PUT /todo/ :修改一个代办事项。通过 URL 参数获取代办事项的 ID 并更新对应的记录。
  6. DELETE /todo/ :删除一个代办事项。通过 URL 参数获取代办事项的 ID 并从数据库删除。

总结

这段代码实现了一个简单的代办事项(Todo)管理系统,包含以下功能:

  • 创建代办事项
  • 查看特定代办事项
  • 查看所有代办事项
  • 修改代办事项
  • 删除代办事项

使用 Gin 框架处理 HTTP 请求,使用 GORM 处理 MySQL 数据库操作。

整个代码逻辑并不复杂,只是时间过的比较久了,gorm的对应命令进行一些调整,所以代码也需要进行对应的改动。

参考

https://www.bilibili.com/video/BV1gJ411p7xC/?spm_id_from=333.337.search-card.all.click&vd_source=59fd7d01b725c7ff09c3a0e6221d9016

0 人点赞