Gin+Gorm练手小项目bubble清单企业级结构剖析

概述

本项目来源于Qimi老师的小清单项目——基于gin+gorm开发的练手小项目,通过该项目可初识go web开发该有的姿势。笔者对代码有些许修改,以下是项目成功运行的截图,主要功能有添加,删除,确认,查看待办事项等(所以是小项目啦~)
在这里插入图片描述

项目结构树

这个项目虽然比较小,但是还是可以用企业级代码结构去划分,以下是项目结构树:

├─controllers
├─dao
├─models
├─routers
├─static
│  ├─css
│  ├─fonts
│  └─js
└─template

在这里插入图片描述
划分项目结构,利于代码组织和可维护,也有利于团队协作。

后端源码

main.go

package mainimport ("bubble/dao""bubble/models""bubble/routers"
)func main() {err := dao.InitMySQL()if err != nil {panic(err)}err = dao.DB.AutoMigrate(&models.Todo{})if err != nil {panic(err)}r := routers.SetupRouter()err = r.Run()if err != nil {panic(err)}
}

controller.go

package controllersimport ("bubble/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 CreateTodo(c *gin.Context) {var todo models.Todoerr := c.BindJSON(&todo)if err != nil {panic(err)}if err := models.CTodo(&todo); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})} else {c.JSON(http.StatusOK, gin.H{"code": 200,"msg":  "success","data": todo,})}
}func GetTodo(c *gin.Context) {if todoList, err := models.GTodo(); err != nil {c.JSON(http.StatusBadRequest, err.Error())} else {c.JSON(http.StatusOK, todoList)}
}func UpdateTodo(c *gin.Context) {id, ok := c.Params.Get("id")if !ok {c.JSON(http.StatusBadRequest, gin.H{"error": "无效的id"})return}todo, err := models.UTodo(id)if err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}err = c.BindJSON(&todo)if err != nil {panic(err)}if err = models.STodo(todo); err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error()})} else {c.JSON(http.StatusOK, todo)}
}func DeleteTodo(c *gin.Context) {id, ok := c.Params.Get("id")if !ok {c.JSON(http.StatusOK, gin.H{"error": "无效的id"})return}if err := models.DTodo(id); err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error()})} else {c.JSON(http.StatusOK, gin.H{id: "deleted"})}
}

mysql.go

package daoimport ("gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc InitMySQL() (err error) {dsn := "root:@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})return err
}

todo.go

package modelsimport ("bubble/dao"
)// Todo Model
type Todo struct {ID     int    `json:"id"`Title  string `json:"title"`Status bool   `json:"status"`
}//Todo 增删改查// CTodo 创建todo
func CTodo(todo *Todo) (err error) {if err = dao.DB.Create(&todo).Error; err != nil {return err}return
}// GTodo 查询todo
func GTodo() (todoList []*Todo, err error) {err = dao.DB.Find(&todoList).Errorreturn
}func UTodo(id string) (todo *Todo, err error) {if err := dao.DB.Where("id=?", id).First(&todo).Error; err != nil {return nil, err}return
}func STodo(todo *Todo) (err error) {err = dao.DB.Save(&todo).Errorreturn
}func DTodo(id string) (err error) {err = dao.DB.Where("id=?", id).Delete(&Todo{}).Errorreturn
}

routers.go

package routersimport ("bubble/controllers""github.com/gin-gonic/gin"
)func SetupRouter() *gin.Engine {r := gin.Default()r.Static("/static", "static")r.LoadHTMLGlob("template/*")r.GET("/", controllers.IndexHandler)v1Group := r.Group("/v1"){v1Group.POST("/todo", controllers.CreateTodo)v1Group.GET("todo/", controllers.GetTodo)v1Group.PUT("todo/:id", controllers.UpdateTodo)v1Group.DELETE("todo/:id", controllers.DeleteTodo)}return r
}

学习使用

前后端所有源码都已经上传至我的资源里:https://download.csdn.net/download/m0_63230155/88064315?spm=1001.2014.3001.5503,供其他小伙伴学习使用,这个是免费下载的!

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

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

相关文章

05 信号与槽机制

信号(Signal): 信号的本质是事件,例如鼠标点击,窗口刷新,键盘输入等 槽(Slot): 槽的本质是信号对应的函数,可以有参,可以发生重载 信号与槽机制…

有哪些记事本app可以用来整理个人笔记?

我总是在思考一个问题,为什么现在越来越多的人选择使用记事本app?它们相比传统笔记本,又有什么吸引人的地方呢?这其实并不难理解。因为,记事本app不仅可以让我们及时记录重要信息,还能对这些信息进行系统、…

Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】

相关文章: Django实现接口自动化平台(八)测试报告reports序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 本章是项目的一个分解,查看本章内容时,要结合整体项目代码来看: python django vue …

mac 下 geoserver 安装

一、去官网下载geoserver https://geoserver.org/ 选择一个版本,然后点进去 二、需要配置java环境和设置geoserver 环境变量 1)、java 环境安装 Java Downloads | Oracle 中国 2)、环境变量设置 1.打开终端:command 空格键 2…

Python自动获取字母站视频

如果有疑问的话可以在我的谈论群:706128290 来找我 目录 前言 二、编写代码 1.引入库 2.编写主类 3. 自动获取cookies值和生成headers 4.获取命令行参数 运行效果 前言 browser_cookie3 第三方模块 browser_cookie3是browser_cookie模块的分支,…

jupyter notebook更换虚拟环境(内核)

jupyter notebook更换虚拟环境(内核) 创建一个新的虚拟环境 # stk_env 虚拟环境的名字,任取。 conda create -n stkenv python3.9激活虚拟环境 conda activate stkenv安装ipykernel # 为该虚拟环境,安装内核。 conda install -c a…

基于C语言设计的足球信息查询系统

完整资料进入【数字空间】查看——baidu搜索"writebug" 需求分析与概要设计 2.1 项目说明 我们小组的选题主要是面向足球爱好者,在普通社交软件的基础之上,围绕足球的主题展开设计,以便于他们能够更好的交流相关的话题&#xff…

LangChain(2)提示工程 Prompt Engineering

提示一般包含如下部分: Instructions:整体结构,模型的人设 Instructions tell the model what to do, how to use external information if provided, what to do with the query, and how to construct the output. External information&a…

linux之Ubuntu系列(六)用户管理 终端命令 which 查看执行命令所在的位置

提示 /etc/passwd 是用于保存用户信息的文件 可以用cat 命令查看 cat /etc/passwd/usr/bin/passwd 是用于修改用户密码的 程序 ,是程序 程序 , which 命令 可以查看执行命令所在的位置 # 输出 /bin/ls which ls # 输出 /usr/sbin/useradd which useradd…

话费电费中控搭建,api接口h5,公众号,小程序app

话费充值接口文档 接口版本:1.0 ―、引言 文档概述 本文档提供话费充值接口规范说明,提供一整套的完整的接入示例(http 接口)供商户参 考,可以帮助商户开发人员快速完成接口开发与联调,实现与话费充值系统的交易互联。 公司官网…

【算法第六天7.19】反转字符串,反转字符串||,剑指 Offer 05. 替换空格,反转字符串的单词, 左旋转字符串

链接:力扣344-反转字符串 链接:力扣541-反转字符串|| 链接:剑指 Offer 05. 替换空格 链接:力扣151- 反转字符串的单词 链接:剑指 Offer 58 - II. 左旋转字符串 链接:力扣344-反转字符串 思路&#xff…

git clone 或者是vscode clone 时遇到the remote end hung up unexpectedly

fatal: the remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed使用git clone总是报错 查看原因有三种可能:要么是缓存不够,要么是网络不行,要么墙的原因。 如果是网络不行,可以配置git的最低速度和最…

C#基础--线程之Task

C#基础–线程之Task Task 是.NetFramework3.0出现的,Task里面的线程是来自于线程池 一、Task 1. 开启一个线程 Task 构造函数 传入一个无参数的 Action 委托作为参数 Task task = new Task(() =>{this.DoSomethingLong("btntask_Click1");}); task.Start();Run…

局部响应归一化LRN(Local Response Normalization)

LRN(Local Response Normalization)是一种局部响应归一化的技术,在深度学习中常用于增强模型的泛化能力和对光照、对比度等变化的鲁棒性。LRN主要用于激活函数后的归一化过程,它对局部神经元响应进行归一化,使得响应较…

C/C++ 使用 define 实现运行时函数是在哪个文件哪个函数被调用

1. 原始代码 // demo2.h #include <iostream>void testFunc(int num) {std::cout << num << std::endl; }//main.cc #include "demo2.h"void func1() { }void func2() {testFunc(24); }int main() {func1();func2();return 0; }我现在需要知道 te…

re学习(19)[ACTF新生赛2020]easyre1(UPX脱壳)

文章链接&#xff1a;BUUCTF在线评测 参考视频&#xff1a;B站 【新手教程三】小Z带你学习什么是ESP定律和什么是堆栈平衡 &#xff1f; - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn 题解&#xff1a; 工具脱壳 key"*F\"N,\"…

MYSQL数据库-数据库的学习

MYSQL数据库-数据库的学习 MYSQL数据库一、数据库的基本概念二、常见的数据库三、MySQL数据库四、SQL操作五、SQL高级操作六、SQL函数&#xff08;SQL 拥有很多可用于计数和计算的内建函数) MYSQL数据库 一、数据库的基本概念 1、数据库的英文单词:DataBase 简称 : DB 2、什么…

C#基础--进程和线程的认识

C#基础–进程和线程的认识 一、基础概念 1. 什么是进程? 进程并不是物理的东西,是虚拟出来的,是一种概念。当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。是一种计算机概念,是程序在运…

【矩阵的创建与基本运算】——matlab基础

目录索引 创建矩阵&#xff1a;zeros()&#xff1a;ones&#xff1a;eye()&#xff1a;magic()&#xff1a;引号创建序列矩阵&#xff1a;linspace()&#xff1a; 加减与数乘&#xff1a;其他运算&#xff1a;指数运算&#xff1a;*exp()&#xff1a;* 点式运算&#xff1a; 创…

Fiddler抓包app(方便后端定位app调用的是那个接口?参数为何?)

一、抓http请求的包 1、设置Fiddler允许远程连接 选择Tools->Options 选择Connections选项卡&#xff0c;选中允许远程连接&#xff0c;如图所示 2、手机与电脑连接相同的wlan网络 3、手机wlan设置手动代理&#xff0c; 1&#xff09;手动代理的主机名设为电脑ip&…