gorm/gin框架实战

gorm/gin框架实战

项目简介

学习源视频:【最新Go Web开发教程】基于gin框架和gorm的web开发实战 (七米出品)_哔哩哔哩_bilibili

本博客为我的学习笔记。

项目目标:实现一个备忘录工具(当然不支持alert),仅仅是可以记录待办事项。

实现了:添加待办项、删除待办项、完成待办项、查询待办项

项目主页展示:

image-20240603161443744

添加、查询待办项展示:

image-20240603161731924

删除待办项展示:

image-20240603163615841

项目框架

可以看看之前同专栏的博客,这是一个很基本的框架

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"net/http"
)

type Todo struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Status bool   `json:"status"`
}

var (
	DB *gorm.DB
)

func initMySQL() (err error) {
	
}

func main() {
	//连接数据库
	err := initMySQL()
	if err != nil {
		panic(err)
	}
	defer DB.Close() //关闭数据库连接
	//模型绑定
	DB.AutoMigrate(&Todo{})
	r := gin.Default()
	//设置静态资源文件
	r.Static("/static", "static")
	// 设置gin框架模版文件
	r.LoadHTMLGlob("templates/*")

	//设置路由
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})
	//设置路由组
	v1Group := r.Group("/v1")
	{
		//添加一个事项
		v1Group.POST("/todo", func(c *gin.Context) {
			
		})
		//查看一个事项
		v1Group.GET("/todo/:id", func(c *gin.Context) {

		})
		//查看所有事项
		v1Group.GET("/todo/", func(c *gin.Context) {
			
		})
		//修改一个事项
		v1Group.PUT("/todo/:id", func(c *gin.Context) {

		})
		//删除一个事项
		v1Group.DELETE("/todo/:id", func(c *gin.Context) {

		})
	}
	r.Run()
}

接口填充

数据库连接

DB, err = gorm.Open("mysql", "usr1:12345@tcp(***:3306)/db1?charset=utf8&parseTime=True&loc=Local")
if err != nil {
    panic(err)
}
return DB.DB().Ping()

添加一个事项

v1Group.POST("/todo", func(c *gin.Context) {
    //前端页面填写待办事项,点击提交,会发送请求到这
    //1.从请求中把数据拿出来
    var todo Todo
    c.BindJSON(&todo)
    fmt.Println(todo)
    //2.存入数据库 + 3.返回响应
    if err = DB.Create(&todo).Error; err != nil {
        c.JSON(http.StatusOK, gin.H{
            "error": err.Error(),
        })
    } else {
        c.JSON(http.StatusOK, todo)
    }
})

查看所有事项

//查看一个事项
v1Group.GET("/todo/:id", func(c *gin.Context) {
    //...一般用不到
})
//查看所有事项
v1Group.GET("/todo/", func(c *gin.Context) {
    var todoList []Todo

    if err = DB.Find(&todoList).Error; err != nil {
        c.JSON(http.StatusOK, gin.H{
            "error": err.Error(),
        })
    } else {
        fmt.Println(todoList)
        c.JSON(http.StatusOK, todoList)
    }
})

修改一个事项

//修改一个事项
v1Group.PUT("/todo/:id", func(c *gin.Context) {
    id, ok := c.Params.Get("id")
    if !ok {
        c.JSON(http.StatusOK, gin.H{
            "error": "无效的id",
        })
        return
    }
    var todo Todo
    if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
        c.JSON(http.StatusOK, gin.H{
            "error": err.Error(),
        })
    } else {
        c.BindJSON(&todo)
        if err = DB.Save(&todo).Error; err != nil {
            c.JSON(http.StatusOK, gin.H{
                "error": err.Error(),
            })
        } else {
            c.JSON(http.StatusOK, todo)
        }
    }
})

删除一个事项

//删除一个事项
v1Group.DELETE("/todo/:id", func(c *gin.Context) {
    id, ok := c.Params.Get("id")
    if !ok {
        c.JSON(http.StatusOK, gin.H{
            "error": "无效的id",
        })
        return
    }
    if err = DB.Where("id=?", id).Delete(Todo{}).Error; err != nil {
        c.JSON(http.StatusOK, gin.H{
            "error": err.Error(),
        })
    } else {
        c.JSON(http.StatusOK, gin.H{
            id: "delete",
        })
    }
})

ApiPost接口测试

添加接口

image-20240603165318647

image-20240603165544890

查看接口

image-20240603165337290

修改接口

image-20240603165451043

删除接口

image-20240603165524808

image-20240603165617457

企业级项目划分

1.controller

控制器:控制路由进来后执行的函数

package controller

import (
	"fmt"
	"gin_demo_BubbleList/models"
	"github.com/gin-gonic/gin"
	"net/http"
)

/*
url -> controller -> logic -> model
请求 -> 控制器 -> 业务逻辑 -> 模型层的增删改查
*/
func IndexHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", nil)
}

func Create(c *gin.Context) {
	//前端页面填写待办事项,点击提交,会发送请求到这
	//1.从请求中把数据拿出来
	var todo models.Todo
	c.BindJSON(&todo)
	fmt.Println(todo)
	//2.存入数据库 + 3.返回响应
	err := models.CreateTodo(&todo)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"error": err.Error(),
		})
	} else {
		c.JSON(http.StatusOK, todo)
	}
	//if err = DB.Create(&todo).Error; err != nil {
	//	c.JSON(http.StatusOK, gin.H{
	//		"error": err.Error(),
	//	})
	//} else {
	//	c.JSON(http.StatusOK, todo)
	//}
}

func GetTodoList(c *gin.Context) {
	todoList, err := models.GetTodoList()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"error": err.Error(),
		})
	} else {
		fmt.Println(todoList)
		c.JSON(http.StatusOK, todoList)
	}
	//if err = DB.Find(&todoList).Error; err != nil {
	//	c.JSON(http.StatusOK, gin.H{
	//		"error": err.Error(),
	//	})
	//} else {
	//	fmt.Println(todoList)
	//	c.JSON(http.StatusOK, todoList)
	//}
}

func UpdateById(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{
			"error": "无效的id",
		})
		return
	}
	todo, err := models.GetTodoById(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"error": err.Error(),
		})
		return
	}
	//var todo Todo
	//if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
	//	c.JSON(http.StatusOK, gin.H{
	//		"error": err.Error(),
	//	})
	//	return
	//}
	c.BindJSON(&todo)
	if err = models.UpdateTodoById(todo); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"error": err.Error(),
		})
	} else {
		c.JSON(http.StatusOK, todo)
	}
}

func DeleteById(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{
			"error": "无效的id",
		})
		return
	}
	err := models.DeleteTodo(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"error": err.Error(),
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			id: "delete",
		})
	}
	//if err = DB.Where("id=?", id).Delete(Todo{}).Error; err != nil {
	//	c.JSON(http.StatusOK, gin.H{
	//		"error": err.Error(),
	//	})
	//} else {
	//	c.JSON(http.StatusOK, gin.H{
	//		id: "delete",
	//	})
	//}
}

2.models

模具:模型+业务逻辑(ps:可以分开)

package models

import (
	"gin_demo_BubbleList/dao"
)

type Todo struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	Status bool   `json:"status"`
}

// Todo 增删改查
// CreateTodo 创建一个Todo
func CreateTodo(todo *Todo) (err error) {
	err = dao.DB.Create(&todo).Error
	return
}

// GetTodoList 获取全部的Todo
func GetTodoList() (todoList []*Todo, err error) {
	if err = dao.DB.Find(&todoList).Error; err != nil {
		return nil, err
	}
	return
}

// GetTodoById 通过id获取一个Todo对象
func GetTodoById(id string) (todo *Todo, err error) {
	todo = new(Todo)
	if err = dao.DB.Where("id=?", id).First(&todo).Error; err != nil {
		return nil, err
	}
	return
}

// UpdateTodoById 更新一个Todo对象
func UpdateTodoById(todo *Todo) (err error) {
	err = dao.DB.Save(todo).Error
	return
}

// DeleteTodo
func DeleteTodo(id string) (err error) {
	err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error
	return
}

3.dao

dao:存放关于数据库的相关操作

package dao

import "github.com/jinzhu/gorm"

var (
	DB *gorm.DB
)

func InitMySQL() (err error) {
	DB, err = gorm.Open("mysql", "usr1:12345@tcp(***:3306)/db1?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	return DB.DB().Ping()
}

4.router

router:一般用于设置路由

package router

import (
	"gin_demo_BubbleList/controller"
	"github.com/gin-gonic/gin"
)

func SetRouter() *gin.Engine {
	r := gin.Default()
	//设置静态资源文件
	r.Static("/static", "static")
	// 设置gin框架模版文件
	r.LoadHTMLGlob("templates/*")

	//设置路由
	r.GET("/", controller.IndexHandler)
	//设置路由组
	v1Group := r.Group("/v1")
	{
		//添加一个事项
		v1Group.POST("/todo", controller.Create)
		//查看所有事项
		v1Group.GET("/todo/", controller.GetTodoList)
		//修改一个事项
		v1Group.PUT("/todo/:id", controller.UpdateById)
		//删除一个事项
		v1Group.DELETE("/todo/:id", controller.DeleteById)
	}
	return r
}

4.整体架构

image-20240603175629138

我的源码:6月/gin_demo_BubbleList · 沉着冷静/2023 - 码云 - 开源中国 (gitee.com)

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值