【Go】-基于Gin和GORM的小清单项目

打印 上一主题 下一主题

主题 1032|帖子 1032|积分 3096

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
项目先容
简介
技术
项目结构
项目分析
总结 


项目先容

简介

        项目地址:knoci/list: 基于Gin的待办清单小项目 (github.com)
        一个仿照github/Q1mi/bubble 做的一个gin框架练习
技术



  • gin 框架
  • gorm 操纵PostgreSQL
  • ini 配置文件
项目结构

  1. list
  2. ├── README.md
  3. ├── config
  4. │   └── config.ini
  5. ├── controller
  6. │   └── controller.go
  7. ├── dao
  8. │   └── postgresql.go
  9. ├── go.mod
  10. ├── go.sum
  11. ├── main.go
  12. ├── models
  13. │   └── todo.go
  14. ├── routers
  15. │   └── routers.go
  16. ├── static
  17. │   ├── css
  18. │   │   ├── app.8eeeaf31.css
  19. │   │   └── chunk-vendors.57db8905.css
  20. │   ├── fonts
  21. │   │   ├── element-icons.535877f5.woff
  22. │   │   └── element-icons.732389de.ttf
  23. │   └── js
  24. │       ├── app.007f9690.js
  25. │       └── chunk-vendors.ddcb6f91.js
  26. └── templates
  27.     ├── favicon.ico
  28.     └── index.html
复制代码

项目分析

        项目中有config,controllers,dao,models,routers,static,template这7个文件夹。


  • config生存ini文件,配置毗连数据库的参数(Port,User,Password...)
  • controllers生存控制函数,实现器功能,处理web相应
  • dao毗连数据库
  • models是各种数据结构模板界说
  • routers负责路由分组和路由处理
  • static存储静态资源
  • template是前端模板
        接下来我们从mian.go开始,逐步分析整个项目的运行。
  1. package main
  2. import (
  3.         "list/dao"
  4.         "list/models"
  5.         "list/routers"
  6.         //_ "gorm.io/driver/mysql"
  7.         _ "gorm.io/driver/postgres"
  8. )
  9. func main() {
  10.         //连接数据库
  11.         dao.Connect()
  12.         //模型绑定
  13.         dao.DB.AutoMigrate(&models.Todo{})
  14.         //启动router
  15.         routers.SetupRouter()
  16. }
复制代码
        在main.go中我们导入了同文件夹下的dao,models,routers;随后运行第一个函数 dao.Connect(),接下来我们进入dao,来看看 dao.Connect() 函数实现了什么功能
  1. package dao
  2. import (
  3.         "fmt"
  4.         "gopkg.in/ini.v1"
  5.         //"gorm.io/driver/mysql"
  6.         "gorm.io/driver/postgres"
  7.         "gorm.io/gorm"
  8. )
  9. var (
  10.         DB *gorm.DB
  11. )
  12. type MysqlConfig struct {
  13.         User     string `ini:"user"`
  14.         Password string `ini:"password"`
  15.         Host     string `ini:"host"`
  16.         Port     string `ini:"port"`
  17.         DBname   string `ini:"db"`
  18. }
  19. func LoadConfig() *MysqlConfig {
  20.         //development_通过结构体映射参数
  21.         c := new(MysqlConfig)
  22.         ini.MapTo(c, "config/config.ini")
  23.         fmt.Println(c)
  24.         return c
  25. }
  26. func Connect() {
  27.         c := LoadConfig()
  28.         dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s", c.Host, c.User, c.Password, c.DBname, c.Port)
  29.         /* mysql
  30.         dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",c.User, c.Password, c.Host, c.Port, c.DBname)
  31.         dsn := "root:root1234@tcp(127.0.0.1:13306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
  32.         */
  33.         var err error
  34.         DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) // connect
  35.         // mysql DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
  36.         if err != nil {
  37.                 panic(err.Error())
  38.         }
  39.         fmt.Print("==========连接数据库成功==========\n")
  40. }
复制代码
        在postgresql.go中导入了GORM,PG驱动,ini包,自界说告终构体Mysqlconfig,和一个 导包全局可访问的 gorm.DB范例的指针DB,封装了一个函数 LoadConfig() 通过ini.MapTo(c, "config/config.ini") 来接收配置文件。
        在Connect函数中调用LoadConfig()获得配置,用Sprintf()把配置复制到dsn,然后通过gorm.Open方法毗连到我们的数据库。
        dao.Connect()完成后,我们继承回到main.go,用dao包内变量DB的内置方法 dao.DB.AutoMigrate(&models.Todo{}) ,实现了模型绑定,现实上就是按照models.Todo结构体在数据库中创建了一张表。
  1. package models
  2. type Todo struct {
  3.         ID     int    `json:"id"`
  4.         Title  string `json:"title"`
  5.         Status bool   `json:"status"`
  6. }
复制代码
        Todo表中,每个待服务项有ID,Title,Status,并且有相应JOSN的tag。此中ID是用来标识事项的自增唯一值,Title是事务名,Status用0和1体现未完成和完成。
        回到main.go,最后调用了routers.SetupRouter(),这是在本地routers包routers.go里的函数。在SetupRouter中,使用gin.Default()注册默认路由r;然后用r.Static()导入./static目录下静态文件指定为static;接着用r.LoadHTMLGlob()导入当前路径template/*的模板。
        接着就是路由处理,指定了对"/"的GET哀求回应controllers.ShowIndex函数,用r.Group()界说了路由组v1Group。
        路由组中,指定了对"todo"的POST哀求回应controllers.CreateTodo函数,对"/todo"的GET哀求回应controllers.RetrieveTodo函数,对"/todo/:id"的PUT哀求回应controllers.UpdateTodo函数,对"/todo/:id"的DELETE哀求回应controllers.DeleteTodo函数。
        最后用r.Run(:9090),在9090端口上监听并运行。
  1. package routers
  2. import (
  3.         "github.com/gin-gonic/gin"
  4.         "list/controllers"
  5. )
  6. func SetupRouter() {
  7.         r := gin.Default()
  8.         r.Static("/static", "static")
  9.         r.LoadHTMLGlob("template/*")
  10.         r.GET("/", controllers.ShowIndex)
  11.         v1Group := r.Group("v1")
  12.         {
  13.                 //添加
  14.                 v1Group.POST("todo", controllers.CreateTodo)
  15.                 //查看
  16.                 v1Group.GET("/todo", controllers.RetrieveTodo)
  17.                 //修改
  18.                 v1Group.PUT("/todo/:id", controllers.UpdateTodo)
  19.                 //删除
  20.                 v1Group.DELETE("/todo/:id", controllers.DeleteTodo)
  21.         }
  22.         r.Run(":9090")
  23. }
复制代码
        接下来看看controller中的各个函数的功能,首先是ShowIndex,负责返回状态码200,展示index.html。
  1. func ShowIndex(c *gin.Context) {
  2.         c.HTML(http.StatusOK, "index.html", nil)
  3. }
复制代码
        CreateTodo 用来创建一个待服务项。在接收到传来的数据后,界说一个models.Todo范例的todo结构体,然后用 c.ShouldBind(&todo) 自动的进行相应格式(这里是JSON)的参数绑定到todo,然后通过 dao.DB.Create(&todo) 把todo存入数据库DB,以JSON格式失败返回报错,乐成返回todo。
  1. func CreateTodo(c *gin.Context) {
  2.         //get data
  3.         var todo models.Todo
  4.         c.ShouldBind(&todo)
  5.         //add into database
  6.         err := dao.DB.Create(&todo).Error
  7.         //return
  8.         if err != nil {
  9.                 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  10.                 return
  11.         } else {
  12.                 c.JSON(http.StatusOK, todo)
  13.         }
  14. }
复制代码
        RetrieveTodo 用来获取所有待服务项,创建一个结构体数组todos,用 dao.DB.Find(&todos) 把所有的表数据给到todos,以JSON格式失败返回报错,乐成返回todos。
  1. func RetrieveTodo(c *gin.Context) {
  2.         var todos []models.Todo
  3.         if err := dao.DB.Find(&todos).Error; err != nil {
  4.                 c.JSON(http.StatusOK, gin.H{"error": err.Error()})
  5.                 return
  6.         } else {
  7.                 c.JSON(http.StatusOK, todos)
  8.         }
  9. }
复制代码
         UpdateTodo 用来更新指定的事项,用 c.Params.GET("id") 获得要修改事项名为"id"的指定url,界说todo结构体然后用 dao.DB.Where("id=?", id).First(&todo) 来查询数据库中第一个对应id的数据到todo,然后 c.BindJSON(&todo) 把方法哀求体c以JSON绑定到todo,最后 dao.DB.Save(&todo) 来更新数据库。
  1. func UpdateTodo(c *gin.Context) {
  2.         id, ok := c.Params.Get("id")
  3.         if !ok {
  4.                 c.JSON(http.StatusOK, gin.H{"error": "id invalid"})
  5.                 return
  6.         }
  7.         var todo models.Todo
  8.         if err := dao.DB.Where("id=?", id).First(&todo).Error; err != nil {
  9.                 c.JSON(http.StatusOK, gin.H{"error": err.Error()})
  10.                 return
  11.         }
  12.         c.BindJSON(&todo) //修改
  13.         if err := dao.DB.Save(&todo).Error; err != nil {
  14.                 c.JSON(http.StatusOK, gin.H{"error": err.Error()})
  15.         } else {
  16.                 c.JSON(http.StatusOK, todo)
  17.         }
  18. }
复制代码
        DeletTodo 用来删除一个待服务项,照旧通过 c.Params.GET("id") 获得要修改事项名为"id"的指定url,用 dao.DB.Where("id=?", id).Delete(models.Todo{}) 来删除数据库中对应id的数据,由于这里不接收哀求体,没有界说局部变量结构体,以是直接传入model.Todo{}指定表格式。

总结 

        这个项目是Gin和GORM的非常非常简单的小项目,得当新手入门。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊雷无声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表