gorm/gin框架实战

gorm/gin框架实战

项目简介

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

本博客为我的学习笔记。

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

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

项目主页展示:

image-20240603161443744

添加、查询待办项展示:

image-20240603161731924

删除待办项展示:

image-20240603163615841

项目框架

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

package mainimport ("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 Todoc.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 []Todoif 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 Todoif 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 controllerimport ("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.Todoc.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 modelsimport ("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).Errorreturn
}// 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).Errorreturn
}// DeleteTodo
func DeleteTodo(id string) (err error) {err = dao.DB.Where("id=?", id).Delete(&Todo{}).Errorreturn
}

3.dao

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

package daoimport "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 routerimport ("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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

川北医学院与爱尔眼科医院集团签署战略合作协议共谋医学发展新篇章

为深入贯彻落实党的二十大精神,统筹校、企、医、政多方资源,服务“健康中国”战略,推动眼健康产业发展,打造国家及区域级眼科医学中心,2024年5月31日,川北医学院与爱尔眼科医院集团在成都举行战略合作协议签…

数字化校园建设让学习更加广阔

校园构建数字化校园的亮点是什么?校园以智能服务、才智办理、数字讲堂为中心内容的智慧校园建造,不只使师生作业和日子更高效,并且使他们有更多的时刻投入到智能教育和智能学习中去,进步教育质量,使学生走出校门时紧跟…

代码随想录第23天|回溯part3 组合与分割

39.组合总和 class Solution { public:vector<vector<int>> res;vector<int> path;void backTracking(vector<int>& candidates,int target,int sum,int n,int step){if(n > 150) return;if(sum > target) return;if(sum target){res.push_…

Scikit-Learn随机森林分类

Scikit-Learn随机森林分类 1、随机森林分类1.1、随机森林分类概述1.2、随机森林分类的优缺点2、Scikit-Learn随机森林分类2.1、Scikit-Learn随机森林分类API2.2、Scikit-Learn随机森林分类初体验(葡萄酒分类)2.3、Scikit-Learn随机森林分类实践(鸢尾花分类)2.4、参数调优与…

微信支付(可复用)

3.1微信支付 本项目选择小程序支付 参考&#xff1a;产品中心 - 微信支付商户平台微信支付商户平台提供各类支付产品满足商家通过微信支付收款的需求&#xff1b;平台提供智慧经营&#xff0c;现金红包&#xff0c;代金券等运营工具&#xff0c;助力商家更好的玩转营销&#x…

程序员应该有什么职业素养?

程序员的六大职业素养&#xff1a;构建成功职业生涯的基石 在不断变化的技术世界中&#xff0c;程序员不单要保持技术的锋利&#xff0c;也需要培养相应的职业素养&#xff0c;这些素养在很大程度上决定了一个程序员的职业生涯能否走得长远。以下是我认为最为重要的六大职业素…

LLM基础知识

LLM背景知识介绍 1 大语言模型 (LLM) 背景 大语言模型 (英文&#xff1a;Large Language Model&#xff0c;缩写LLM) 是一种人工智能模型, 旨在理解和生成人类语言. 大语言模型可以处理多种自然语言任务&#xff0c;如文本分类、问答、翻译、对话等等。 &#x1f4a5;通常&…

NVIDIA - QPU

转载自 What Is a QPU? ( 2022 年 7 月 29 日 里克梅里特 https://blogs.nvidia.com/blog/what-is-a-qpu/ 文章目录 一、概述二、那么&#xff0c;什么是 QPU&#xff1f;三、量子处理器如何工作&#xff1f;四、制作量子比特的多种方法五、光的量子比特六、简单的芯片&#x…

git commit使用husky校验代码格式报错,没有将钩子 ‘.huskypre-commit‘ 设置为可执行,钩子被忽略。

使用git提交代码时&#xff0c;通过husky校验代码格式&#xff0c;终端报错 因为没有将钩子 .husky/pre-commit 设置为可执行 系统&#xff1a;Mac husky 在 Windows 上能够正常运行 解决办法 # 没有权限就给个权限 使用 chmod x 给权限 # 通过这行命令解决husky钩子不执行…

【C#】类和结构体的区别

目录 1.区别概述 ​编辑 2.细节区别 3.结构体的特别之处 4.如何选择结构体和类 1.区别概述 结构体和类的最大区别是在存储空间上&#xff0c;前者是值类型&#xff0c;存储在栈上&#xff0c;后者是引用类型&#xff0c;存储在堆上&#xff0c;它们在赋值上有很大的区别&a…

【C++入门到精通】C++ thread线程库 [ C++入门 ]

阅读导航 引言一、thread类的简单介绍二、thread类的用法1. 创建线程2. 使用 Lambda 表达式3. 传递参数给线程4. 线程的 join 和 detach5. 检查线程是否可 join6. 线程的 ID7. 线程的移动语义8. 线程的析构&#x1f6a8; 注意事项 三、线程函数参数温馨提示 引言 C thread线程…

实现流程化办公,可以相信拖拽表单设计器!

当前&#xff0c;竞争压力越来越大&#xff0c;利用什么样优良的办公软件实现流程化办公&#xff1f;可以一起来了解低代码技术平台、拖拽表单设计器的优势特点&#xff0c;看看它们是如何助力企业降本、增效、提质的。低代码技术平台的优势特点多&#xff0c;可以助力企业用拖…

轻松实现微信内下载,Xinstall让你的App推广更高效!

在微信中推广App&#xff0c;你是否遇到过这样的困扰&#xff1a;推广链接被微信拦截&#xff0c;用户需要手动复制链接到浏览器才能下载&#xff0c;大大降低了安装率&#xff1f;今天&#xff0c;我们要介绍的Xinstall&#xff0c;就是一款能够解决这一痛点的神器&#xff01…

2.2 OpenCV随手简记(三)

图像的阈值处理定义 &#xff1a;将图像转化为二值图像&#xff08;黑白图&#xff09;, 也可以用于彩色图形&#xff0c;达到夸张的效果 目的&#xff1a;是用来提取图像中的目标物体&#xff0c;将背景和噪声区分开&#xff08;可以近似的认为除了目标全是噪声&#xff09;。…

GSEA的算法只考虑排序吗

其实这个问题很好回答&#xff0c;只需要运行如下代码&#xff0c;如下的基因列表是顺序是完全相同&#xff0c;并且我们只是做了最基础的变换 library(clusterProfiler) library(org.Hs.eg.db)data(geneList, package"DOSE")ego1 <- gseGO(geneList geneLi…

【iOS】UI学习(二)

UI学习&#xff08;二&#xff09; 进度条和滑动条步进器与分栏控件警告对话框和提示等待器UITextFieldUITextField控件UITextFieldDelegate协议 UIScrollView布局子视图手动布局子视图自动布局子视图 进度条和滑动条 下面通过一个程序来讲解该内容&#xff1a; #import <…

Django 里的增删改查

下面是步骤 先更新 urls.py 来添加新的url from django.contrib import admin from django.urls import path from app01 import viewsurlpatterns [path(demo/, views.demo), ]在 models.py 里创建表 from django.db import models# Create your models here. class UserI…

力扣 226. 翻转二叉树

给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ struct TreeNode* invertTree(struct Tr…

[leetcode hot150]第五十七题,插入区间

题目&#xff1a; 给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示…

62. UE5 RPG 近战攻击获取敌人并造成伤害

在上一篇&#xff0c;我们实现了通过AI行为树控制战士敌人靠近攻击目标触发近战攻击技能&#xff0c;并在蒙太奇动画中触发事件激活攻击的那一刻的伤害判断&#xff0c;在攻击时&#xff0c;我们绘制了一个测试球体&#xff0c;用于伤害范围。 在之前实现的火球术中&#xff0c…