【Go】-基于Gin和GORM的小清单项目
目录
项目介绍
简介
技术
项目结构
项目分析
总结
项目介绍
简介
项目地址:knoci/list: 基于Gin的待办清单小项目 (github.com)
一个仿照github/Q1mi/bubble 做的一个gin框架练习
技术
- gin 框架
- gorm 操作PostgreSQL
- ini 配置文件
项目结构
list
├── README.md
├── config
│ └── config.ini
├── controller
│ └── controller.go
├── dao
│ └── postgresql.go
├── go.mod
├── go.sum
├── main.go
├── models
│ └── todo.go
├── routers
│ └── routers.go
├── 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
└── templates├── favicon.ico└── index.html
项目分析
项目中有config,controllers,dao,models,routers,static,template这7个文件夹。
- config保存ini文件,配置连接数据库的参数(Port,User,Password...)
- controllers保存控制函数,实现器功能,处理web响应
- dao连接数据库
- models是各种数据结构模板定义
- routers负责路由分组和路由处理
- static存储静态资源
- template是前端模板
接下来我们从mian.go开始,逐步分析整个项目的运行。
package mainimport ("list/dao""list/models""list/routers"//_ "gorm.io/driver/mysql"_ "gorm.io/driver/postgres"
)func main() {//连接数据库dao.Connect()//模型绑定dao.DB.AutoMigrate(&models.Todo{})//启动routerrouters.SetupRouter()
}
在main.go中我们导入了同文件夹下的dao,models,routers;随后运行第一个函数 dao.Connect(),接下来我们进入dao,来看看 dao.Connect() 函数实现了什么功能。
package daoimport ("fmt""gopkg.in/ini.v1"//"gorm.io/driver/mysql""gorm.io/driver/postgres""gorm.io/gorm"
)var (DB *gorm.DB
)type MysqlConfig struct {User string `ini:"user"`Password string `ini:"password"`Host string `ini:"host"`Port string `ini:"port"`DBname string `ini:"db"`
}func LoadConfig() *MysqlConfig {//development_通过结构体映射参数c := new(MysqlConfig)ini.MapTo(c, "config/config.ini")fmt.Println(c)return c
}func Connect() {c := LoadConfig()dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s", c.Host, c.User, c.Password, c.DBname, c.Port)/* mysqldsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",c.User, c.Password, c.Host, c.Port, c.DBname)dsn := "root:root1234@tcp(127.0.0.1:13306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"*/var err errorDB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) // connect// mysql DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic(err.Error())}fmt.Print("==========连接数据库成功==========\n")
}
在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结构体在数据库中创建了一张表。
package modelstype Todo struct {ID int `json:"id"`Title string `json:"title"`Status bool `json:"status"`
}
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端口上监听并运行。
package routersimport ("github.com/gin-gonic/gin""list/controllers"
)func SetupRouter() {r := gin.Default()r.Static("/static", "static")r.LoadHTMLGlob("template/*")r.GET("/", controllers.ShowIndex)v1Group := r.Group("v1"){//添加v1Group.POST("todo", controllers.CreateTodo)//查看v1Group.GET("/todo", controllers.RetrieveTodo)//修改v1Group.PUT("/todo/:id", controllers.UpdateTodo)//删除v1Group.DELETE("/todo/:id", controllers.DeleteTodo)}r.Run(":9090")}
接下来看看controller中的各个函数的功能,首先是ShowIndex,负责返回状态码200,展示index.html。
func ShowIndex(c *gin.Context) {c.HTML(http.StatusOK, "index.html", nil)
}
CreateTodo 用来创建一个待办事项。在接收到传来的数据后,定义一个models.Todo类型的todo结构体,然后用 c.ShouldBind(&todo) 自动的进行响应格式(这里是JSON)的参数绑定到todo,然后通过 dao.DB.Create(&todo) 把todo存入数据库DB,以JSON格式失败返回报错,成功返回todo。
func CreateTodo(c *gin.Context) {//get datavar todo models.Todoc.ShouldBind(&todo)//add into databaseerr := dao.DB.Create(&todo).Error//returnif err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return} else {c.JSON(http.StatusOK, todo)}}
RetrieveTodo 用来获取所有待办事项,创建一个结构体数组todos,用 dao.DB.Find(&todos) 把所有的表数据给到todos,以JSON格式失败返回报错,成功返回todos。
func RetrieveTodo(c *gin.Context) {var todos []models.Todoif err := dao.DB.Find(&todos).Error; err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error()})return} else {c.JSON(http.StatusOK, todos)}
}
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) 来更新数据库。
func UpdateTodo(c *gin.Context) {id, ok := c.Params.Get("id")if !ok {c.JSON(http.StatusOK, gin.H{"error": "id invalid"})return}var todo models.Todoif err := dao.DB.Where("id=?", id).First(&todo).Error; err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error()})return}c.BindJSON(&todo) //修改if err := dao.DB.Save(&todo).Error; err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error()})} else {c.JSON(http.StatusOK, todo)}
}
DeletTodo 用来删除一个待办事项,还是通过 c.Params.GET("id") 获得要修改事项名为"id"的指定url,用 dao.DB.Where("id=?", id).Delete(models.Todo{}) 来删除数据库中对应id的数据,因为这里不接收请求体,没有定义局部变量结构体,所以直接传入model.Todo{}指定表格式。
总结
这个项目是Gin和GORM的非常非常简单的小项目,适合新手入门。
相关文章:
【Go】-基于Gin和GORM的小清单项目
目录 项目介绍 简介 技术 项目结构 项目分析 总结 项目介绍 简介 项目地址:knoci/list: 基于Gin的待办清单小项目 (github.com) 一个仿照github/Q1mi/bubble 做的一个gin框架练习 技术 gin 框架gorm 操作PostgreSQLini 配置文件 项目结构 list ├── R…...
【银河麒麟高级服务器操作系统】虚拟机服务器执行systemctl提示timeout——分析全过程及处理建议
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 现象描述 产品信息 产品名称 银河麒麟高级服务…...
【Unity错误】No cloud project ID was found by the Analytics SDK
在编译默认的URP 2D项目时,出现这样一个错误:No cloud project ID was found by the Analytics SDK. This means Analytics events will not be sent. Please make sure to link your cloud project in the Unity editor to fix this problem. 原因&…...
2. 变量和指令(omron 机器自动化控制器)——1
机器自动化控制器——第二章 变量和指令 1 2-1 变量一览表MC通用变量轴变量▶ 轴组变量 运动控制指令的输入变量输入变量的有效范围▶ 枚举体一览表 运动控制指令的输出变量运动控制指令的输入输出变量 2-1 变量一览表 MC功能模块使用的变量分为两类。 一类是监视轴等的状态及…...
gpt4最新保姆级教程
如何使用 WildCard 服务注册 Claude3 随着 Claude3 的震撼发布,最强 AI 模型的桂冠已不再由 GPT-4 独揽。Claude3 推出了三个备受瞩目的模型:Claude 3 Haiku、Claude 3 Sonnet 以及 Claude 3 Opus,每个模型都展现了卓越的性能与特色。其中&a…...
Java:继承和多态(1)
在 Java SE 中,继承和多态是面向对象编程(OOP)的两个核心概念。通过继承,子类可以复用父类的代码;而通过多态,子类可以在不修改父类的前提下定义自己的行为。这两者结合起来使得代码更具扩展性、灵活性和可…...
在RabbitMQ中四种常见的消息路由模式
1. Fanout模式 Fanout模式的交换机是扇出交换机(Fanout Exchange),它会将消息广播给所有绑定到它的队列,而不考虑消息的内容或路由键。 工作原理: 生产者发送消息到Fanout Exchange。Fanout Exchange会将消息广播给…...
Android 使用JSON动画:Lottie框架基本使用
Lottie是什么? GitHub的一种跨平台动画解决方案三方框架 使用? 3步 1.引入最新的依赖:https://github.com/airbnb/lottie-android 我写文章时最新版本是6.5.2 添加到 app/build.gradle 文件的以下方法中dependencies {//lottie 动画implementation com.airbnb.android:l…...
【SQL】百题计划 - SQL最基本的判断和查询。
[SQL]百题计划 Select product_id from Products where low_fats "Y" and recyclable "Y";...
C++学习笔记----6、内存管理(五)---- 智能指针(2)
书接上回! make_unique()使用值初始化。例如,将初始类型初始化为0,对象为缺省构造。如果不需要这样的值初始化,例如,因为不管怎么样你都会覆写共初始值,你就可以省略值初始化,通过使用make_uniq…...
游戏出海迎新变局——海外游戏市场有哪些新趋势和新机遇?
游戏出海的热度越来越高,也面临着竞争加剧、门槛提升、成本增加的现实环境,游戏出海有哪些新变化和新趋势? 移动游戏出海的主要海外市场 在海外市场分布方面,美日韩仍然是我国移动游戏重要的海外市场,占据了中国出海…...
【Unity踩坑】创建新项目后提示编译错误要进入安全模式
在创建了新项目后(比如URP,AR,VR),首次打开时提示有编译错误,要进入安全模式。 脚本是项目模板自带的,不会有问题。这时需要先选择进入安全模式,然后关闭项目,重新打开就…...
SpringBoot开发——整合Logbook进行HTTP API请求响应日志输出
文章目录 1. 简介依赖管理2. 实战案例2.1 基本用法2.2 结合Logback日志记录到文件2.3 自定义核心类Logbook2.4 自定义日志输出Sink2.5 与RestTemplate集成1. 简介 记录HTTP API请求响应日志对于监控、调试和性能优化至关重要。它帮助开发者追踪API的使用情况,包括请求来源、参…...
【嵌入式开发 Linux 常用命令系列 7.1 -- git log 只显示日期和主题(title)和commit id】
文章目录 git log 只显示日期和主题(title)和commit id示例其他日期格式选项 git log 只显示日期和主题(title)和commit id 要使用 git log 仅显示提交的日期、提交消息(title)和提交号(commit hash),你可以使用自定义…...
Android Radio2.0——交通公告状态设置(二)
通过前面的学习,我们知道在 Radio 广播中,交通公告(Traffic Announcement, TA)是一个比较重要的概念,它和交通广播(Traffic Radio)是相关的概念,但它们并不完全相同。 一、简介 1、概念介绍 交通公告 定义:交通公告是指在广播中插入的特别信息,通常是关于交通状况…...
用centos安装远程迅雷失败,重写程序做一台下载服务器
安装远程迅雷的时候,要不是安装包地址过期,就是出现64不兼容32的libz.so.1的包,而且32位的libz包也是好多网站过期。 没办法用仅有的python3,用flask搭建了一个小型的内网下载服务器,当然,只要路由器做映射…...
Mysql基础练习题 1407.排名靠前的旅行者(力扣)
编写解决方案,报告每个用户的旅行距离。 # 返回的结果表单,以 travelled_distance 降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。 题目链接: https://leetcode.cn/problems/top-travellers/d…...
一维稳态与非稳态导热的详细分析
目录 引言 一维稳态导热 应用实例:单层平壁导热 数值求解: 一维非稳态导热 应用实例:单层平壁的非稳态导热 温度变化阶段 表格总结: 引言 热传导(Heat Conduction)是热量在物体内部通过微观粒子的相…...
以太坊开发环境
1. 测试网络 可以使用以下命令将以太坊的 Go 语言客户端 Geth 连接到测试网络 [admindaolian ~]$geth --testnet 下图显示了示例输出,该图显示了所选网络的类型以及有关区块链下载的其他各种信息。 Geth 客户端的下载地址如下: https://geth.ethereum…...
深入理解Java虚拟机:Jvm总结-虚拟机字节码执行引擎
第八章 虚拟机字节码执行引擎 8.1 意义 不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果 8.2 运行时栈帧结构…...
电流互感器选型与设计全攻略:励磁电感、匝数比及误差控制实战
摘要: 电流互感器(CT)作为电力监测、过流保护、计量反馈的核心元件,其选型直接影响系统的测量精度与可靠性。工程师常因忽视励磁电感与二次侧负载的匹配导致角差超差,或未考虑暂态饱和特性造成保护误动。本文从CT工作原…...
基于ARM核心板的T-BOX系统设计:从硬件选型到软件实现
1. 项目概述与核心价值最近几年,车联网的概念已经从实验室和展会,实实在在地走进了我们的日常生活。作为一名在嵌入式领域摸爬滚打了十几年的工程师,我亲眼见证了从简单的GPS定位模块,到如今功能高度集成的车载T-BOX(T…...
如何在PowerPoint中高效使用LaTeX进行数学公式排版
如何在PowerPoint中高效使用LaTeX进行数学公式排版 【免费下载链接】latex-ppt Use LaTeX in PowerPoint 项目地址: https://gitcode.com/gh_mirrors/la/latex-ppt 对于需要制作学术演示文稿的科研人员、教师和学生来说,在PowerPoint中排版复杂的数学公式一直…...
微信聊天记录完整导出指南:无需越狱的本地化解决方案
微信聊天记录完整导出指南:无需越狱的本地化解决方案 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 在数字时代,微信聊天记录承载着珍贵的工作沟…...
别再手动忽略.git和.svn了!WinMerge过滤器保姆级配置指南(附常用正则模板)
WinMerge高效过滤指南:彻底告别版本控制与构建文件干扰 接手新项目时,你是否曾被满屏的.git、.svn和.class文件对比结果淹没?WinMerge的过滤器功能正是解决这一痛点的利器。本文将带你从零开始配置专属过滤规则,让文件对比回归核心…...
告别‘天书’!手把手教你用vdex2dex、odex2smali等工具,把Android应用的vdex/odex/cdex转成可读的dex文件
Android逆向工程实战:从vdex/odex/cdex到可读dex的完整指南 当你兴致勃勃地打开一个APK文件准备分析时,却发现里面只有vdex、odex或cdex文件,用JADX直接打开全是乱码——这种挫败感每个逆向工程师都经历过。本文将带你一步步破解这些"天…...
Linux 登录用户、主机名、提示符详解(新手不迷路)
前言刚打开Linux终端,新手总会被一行奇怪的字符搞懵:ubuntuubuntu:~$ —— 这串字符到底是什么意思?“ubuntu”重复出现,冒号、波浪号、美元符号又代表什么?其实,这串字符就是Linux的“提示符”,…...
从黑盒到白盒:Testbench验证机制与FPGA/ASIC开发实践
1. 从“黑盒”到“白盒”:理解Testbench的本质在数字电路设计,尤其是FPGA和ASIC开发领域,我们常常把设计好的硬件描述语言(HDL)模块,比如一个Verilog写的加法器或者一个VHDL写的状态机,称为“待…...
一款支持USB2.0的4端口集线器芯片
GM8220C是成都振芯科技推出的一款支持USB2.0的4端口集线器芯片。它充分满足USB2.0和充电协议(BC1.1/1.2),具备多种工作模式和充电支持功能,适用于多种设备。1. 主要特征协议兼容:兼容USB2.0协议,并向下兼容…...
War3地图制作入门:不用写代码,用触发器和变量也能做出有趣玩法
War3地图制作入门:用触发器和变量打造专属游戏玩法 魔兽争霸3(War3)地图编辑器是游戏史上最强大的玩家创作工具之一,即使没有任何编程基础,也能通过触发器和变量系统创造出令人惊叹的游戏玩法。本文将带你从零开始&…...
