gin+gorm增删改查目录框架
从网上找资料,发现,很多都是直接的结构
路由,后端的controller层,还有model层,都是放在了同一个main.go文件中,如果写项目的话,还得自己去拆文件,拆代码,经过查询和自己总结,下面放一个目录框架
总体目录结构
按照业务流程顺序,解释说明
1、加载自定义封装函数文件、数据库、redis
package mainimport ("ginchat/router""ginchat/utils"
)func main() {utils.InitConfig()utils.InitMysql()utils.InitRedis()r := router.Router()r.Run(":8081")
}
依次的三个函数
system_init.go文件里面
package utilsimport ("fmt""github.com/go-redis/redis/v8""github.com/spf13/viper""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""log""os""time"
)var (DB *gorm.DBerr errorRed *redis.Client
)func InitRedis() {fmt.Print("随便打印点什么,标记一下")Red = redis.NewClient(&redis.Options{Addr: viper.GetString("redis.addr"),Password: viper.GetString("redis.password"),DB: viper.GetInt("redis.DB"),PoolSize: viper.GetInt("redis.poolSize"),MinIdleConns: viper.GetInt("redis.minIdleConn"),})}func InitConfig() {viper.SetConfigName("app")viper.AddConfigPath("config")err := viper.ReadInConfig()if err != nil {fmt.Println(err)}fmt.Println("config app", viper.Get("app"))fmt.Println("config mysql", viper.Get("mysql"))
}func InitMysql() {newLogger := logger.New(//自定义日志模版 打印SQL语句log.New(os.Stdout, "\r\n", log.LstdFlags),logger.Config{SlowThreshold: time.Second, //慢SQL阈值LogLevel: logger.Info, //级别Colorful: true, //彩色},)fmt.Print(newLogger)DB, err = gorm.Open(mysql.Open(viper.GetString("mysql.dns")), &gorm.Config{})if err != nil {fmt.Println("连接数据库失败", err)} else {fmt.Printf("数据库连接成功: %v", DB)}}
2、加载路由文件
package routerimport ("fmt""ginchat/service""github.com/gin-gonic/gin"
)func Router() *gin.Engine {fmt.Print("进入路由了")r := gin.Default()//用户模块r.GET("/user/getUserList", service.GetUserList)r.POST("/user/createUser", service.CreateUser)r.DELETE("/user/deleteUser", service.DeleteUser)r.PUT("/user/updateUser", service.UpdateUser)return r
}
3、这里面的MySQL和Redis配置,可以直接写死在这个文件里面,也可以单独摘出来,放在配置文件中,这里是放在了配置文件中
app.yml中
mysql:dns: admin3:123456@tcp(127.0.0.1:3306)/ginchat?charset=utf8mb4&parseTime=True&loc=Local
redis:addr:"127.0.0.1:6379"password:""DB:0poolSize:30minIdleConn:30
说明一下,dns里面的参数
账号:密码@tcp(ip:端口号)/数据库名字?xxxxxxxx
4、然后,预备的工作就完成了。另外,有一个sql文件下面的testGorm.go文件
package mainimport ("fmt""ginchat/models""gorm.io/driver/mysql""gorm.io/gorm"
)func main() {db, err := gorm.Open(mysql.Open("admin3:123456@tcp(127.0.0.1:3306)/ginchat?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})if err != nil {fmt.Println("连接数据库失败", err)} else {fmt.Printf("数据库连接成功: %v", db)}err2 := db.AutoMigrate(&models.UserBasic{})if err2 != nil {return} else {fmt.Printf("创建表成功: %v", db)}
}
用于临时生成数据表的一个文件,可以去直接执行此函数,生成数据表,或者也可以自己手动去利用navicat去创建表格
这里用到了models包下面的UserBasic{}
package modelsimport ("fmt""ginchat/utils""gorm.io/gorm"
)type UserBasic struct {gorm.ModelName stringPassword stringPhone string `valid:"matches(^1[3-9]{1}\\d{9}$)"`Email string `valid:"email"`Avatar string //头像Identity stringClientIp stringSalt stringClientPort stringLoginTime uint64HeartbeatTime uint64LoginOutTime uint64IsLogout boolDeviceInfo string
}func (table *UserBasic) TableName() string {return "user_basic"
}func GetUserList() []*UserBasic {data := make([]*UserBasic, 10)//fmt.Printf("data的内容为: %v\n", &data)utils.DB.Find(&data)for _, v := range data {fmt.Println(v)}return data}func CreateUser(user UserBasic) *gorm.DB {return utils.DB.Create(&user)
}func DeleteUser(user UserBasic) *gorm.DB {return utils.DB.Delete(&user)
}func UpdateUser(user UserBasic) *gorm.DB {return utils.DB.Model(&user).Updates(UserBasic{Name: user.Name, Phone: user.Phone, Email: user.Email, Password: user.Password, Avatar: user.Avatar})
}func FindUserByName(name string) UserBasic {user := UserBasic{}utils.DB.Where("name=?", name).First(&user)return user
}func FindUserByPhone(phone string) UserBasic {user := UserBasic{}utils.DB.Where("phone=?", phone).First(&user)return user
}func FindUserByEmail(email string) UserBasic {user := UserBasic{}utils.DB.Where("email=?", email).First(&user)return user
}
UserBasic里面需要定义好数据表的字段
5、gorm.Model是gorm包已经先给预先设置好的4个字段
同时,前面是用驼峰式写法,如果不做特殊说明的话,基本上就会转变为下划线方式去设置字段,这个是gorm默认的对应关系
字段名可以控制,字段类型和大小,如果在创建之后不符合自己要求,可以自己额外修改
6、接下来就是后面的调取引用函数了
controller层
package serviceimport ("fmt""ginchat/models""ginchat/utils""github.com/asaskevich/govalidator""github.com/gin-gonic/gin""math/rand""strconv"
)func GetUserList(c *gin.Context) {data := make([]*models.UserBasic, 10)data = models.GetUserList()c.JSON(200, gin.H{"code": 200,"message": data,})
}func CreateUser(c *gin.Context) {user := models.UserBasic{}user.Name = c.PostForm("name")user.Phone = c.PostForm("phone")user.Email = c.PostForm("email")password := c.PostForm("password")rePassword := c.PostForm("repassword")salt := fmt.Sprintf("%06d", rand.Int31())if password != rePassword {c.JSON(200, gin.H{"code": -1,"message": "两次密码不一样!",})return}data1 := models.FindUserByName(user.Name)fmt.Print(data1)if data1.Name != "" {c.JSON(200, gin.H{"code": -1,"message": "用户名不能重复!",})return}data2 := models.FindUserByPhone(user.Phone)fmt.Print(data2)if data2.Phone != "" {c.JSON(200, gin.H{"code": -1,"message": "手机号不能重复!",})return}data3 := models.FindUserByEmail(user.Email)fmt.Print(data3)if data3.Email != "" {c.JSON(200, gin.H{"code": -1,"message": "邮箱不能重复!",})return}user.Password = utils.MakePassword(password, salt)user.Salt = saltmodels.CreateUser(user)c.JSON(200, gin.H{"code": 0,"message": "新增用户成功!",})}func DeleteUser(c *gin.Context) {user := models.UserBasic{}id, _ := strconv.Atoi(c.Query("id"))user.ID = uint(id)models.DeleteUser(user)c.JSON(200, gin.H{"code": 0,"message": "删除用户成功!",})
}func UpdateUser(c *gin.Context) {user := models.UserBasic{}id, _ := strconv.Atoi(c.PostForm("id"))user.ID = uint(id)user.Name = c.PostForm("name")user.Password = c.PostForm("password")user.Phone = c.PostForm("phone")user.Email = c.PostForm("email")_, err := govalidator.ValidateStruct(user)if err != nil {fmt.Print(err)c.JSON(200, gin.H{"code": -1,"message": "修改参数不匹配!",})return} else {fmt.Print(user)models.UpdateUser(user)c.JSON(200, gin.H{"code": 0,"message": "修改用户成功!",})}}
这里举例的是,用户信息表的相关增删改查
另外两个自己封装函数文件,暂时上面几个函数未用到
先贴在这里md5.go和resp.go
package utilsimport ("crypto/md5""encoding/hex""strings"
)// Md5Encode 小写
func Md5Encode(data string) string {h := md5.New()h.Write([]byte(data))tempStr := h.Sum(nil)return hex.EncodeToString(tempStr)
}// MD5Encode 大写
func MD5Encode(data string) string {return strings.ToUpper(Md5Encode(data))
}// MakePassword 加密
func MakePassword(plainpwd, salt string) string {return Md5Encode(plainpwd + salt)
}// ValidPassword 解密
func ValidPassword(plainpwd, salt, password string) bool {return Md5Encode(plainpwd+salt) == password
}
package utilsimport ("encoding/json""net/http"
)type H struct {Code intMsg stringData interface{}Rows interface{}Total interface{}
}func Resp(w http.ResponseWriter, code int, data interface{}, msg string) {w.Header().Set("Content-Type", "application/json")w.WriteHeader(http.StatusOK)h := H{Code: code,Data: data,Msg: msg,}ret, err := json.Marshal(h)if err != nil {panic(err)}w.Write(ret)
}func RespFail(w http.ResponseWriter, msg string) {Resp(w, -1, nil, msg)
}func RespOK(w http.ResponseWriter, data interface{}, msg string) {Resp(w, 0, data, msg)
}func RespOKList(w http.ResponseWriter, data interface{}, total interface{}) {RespList(w, 0, data, total)
}func RespList(w http.ResponseWriter, code int, data interface{}, total interface{}) {w.Header().Set("Content-Type", "application/json")w.WriteHeader(http.StatusOK)h := H{Code: code,Rows: data,Total: total,}ret, err := json.Marshal(h)if err != nil {panic(err)}w.Write(ret)
}
此部分代码是看了B站up主之后总结出来的,感兴趣的可以去搜索看一下
000_项目背景能获得什么技术栈_哔哩哔哩_bilibili
相关文章:

gin+gorm增删改查目录框架
从网上找资料,发现,很多都是直接的结构 路由,后端的controller层,还有model层,都是放在了同一个main.go文件中,如果写项目的话,还得自己去拆文件,拆代码,经过查询和自己总结,下面放…...
python进阶(二)导入import 机制 | 导入import 用法 工作原理全解析
文章目录 1. 整体概念基本介绍1.1 包package1.2 模块 module 2 基本语法2.1 import直接使用2.2 from 及其用法3.1 as的用法 3 工作原理3.1 搜寻3.2 执行3.3 避免导入模块代码执行 参考《Python应该如何导入(import)模块及包》梳理 1. 整体概念基本介绍 …...
极客时间-《罗剑锋的 C++ 实战笔记》文章笔记 + 个人思考
极客时间-《罗剑锋的 C 实战笔记》文章笔记 个人思考 语言特性06 | auto/decltype:为什么要有自动类型推导? 语言特性 06 | auto/decltype:为什么要有自动类型推导? auto 在C 11 引入。 为什么说C是静态强类型语言?…...
Pytorch 对比TensorFlow 学习:Day 17-18: 循环神经网络(RNN)和LSTM
Day 17-18: 循环神经网络(RNN)和LSTM 在这两天的学习中,我专注于理解循环神经网络(RNN)和长短期记忆网络(LSTM)的基本概念,并学习了它们在处理序列数据时的应用。 1.RNN和LSTM基础…...

Java基础 - 07 Set之Set,AbstractSet
上边几篇,我们对java的List集合进行相关介绍,了解了关于List集合下的相关实现类的方法或者接口。 自本篇开始,将围绕java的Set进行介绍,也是对我java知识的巩固吧,处理业务越多,发现自己对基础知识的薄弱&…...
C++17新特性(三)新的标准库组件
1. optional 在编程时,我们经常会遇到可能会返回/传递/使用一个确定类型对象的场景。也就是说,这个对象可能有一个确定类型的值也可能没有任何值。因此,我们需要一种方法来模拟类似指针的语义:通过nullptr表示指针为空。解决方法…...
Spring Boot入门
SpringBoot介绍 什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其中“Boot”的意思就是“引导”,Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速开发 Spring应用的方式。 特点 • 嵌入的 Tomcat,…...

【LeetCode】数学精选4题
目录 1. 二进制求和(简单) 2. 两数相加(中等) 3. 两数相除(中等) 4. 字符串相乘(中等) 1. 二进制求和(简单) 从字符串的右端出发向左做加法,…...

【漏洞复现】Hikvision SPON IP网络对讲广播系统命令执行漏洞(CVE-2023-6895)
文章目录 前言声明一、系统简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 Hikvision Intercom Broadcasting System是中国海康威视(Hikvision)公司的一个对讲广播系统。 声明 请勿利用文章内的相关技术从事非法测试,由于传播…...

IDEA在重启springboot项目时没有自动重新build
IDEA在重启springboot项目时没有自动重新build 问题描述 当项目里面某些依赖或者插件更新了,target的class文件没有找到,导致不是我们需要的效果。 只能手动的清理target文件,麻烦得很 , 单体项目还好说,一次清理就…...

华为设备NAT的配置
实现内网外网地址转换 静态转换 AR1: sys int g0/0/0 ip add 192.168.10.254 24 int g0/0/1 ip add 22.33.44.55 24 //静态转换 nat static global 22.33.44.56 inside 192.168.10.1 动态转换 最多有两台主机同时访问外网 AR1: sys int g0/0/0 ip add…...

48-DOM节点,innerHTML,innerText,outerHTML,outerText,静态获取,单机click,cssText
1.DOM基础 Document Object Module,文档对象模型,window对象,document文档,都可以获取和操作 1)文档节点 2)属性节点(标签内的属性href,src) 3)文本节点(标签内的文字) 4)注释节点 5)元素节点(标签) 2.获取元素节点 2.1通过标签名获取getElementsByTagName() …...

多输入多输出 | Matlab实现基于LightGBM多输入多输出预测
多输入多输出 | Matlab实现基于LightGBM多输入多输出预测 目录 多输入多输出 | Matlab实现基于LightGBM多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现基于LightGBM多输入多输出预测(完整源码和数据) 1.data为数据集&a…...

【欢迎您的到来】这里是开源库get_local_info作者的付费专栏
您好, 我是带剑书生,开源库get_local_info的作者,欢迎您的到来,这里是我的付费专栏,在上一个付费专栏里,用简洁的语言,通俗的话语,帮助您更好的学习了Rust,现在将用本专栏…...
Java SE入门及基础(23)
目录 方法带参 1. 构造方法带参 案例场景 思考:以上代码存在什么问题? 2. 方法带参 方法带参语法 案例场景 思考:以上代码存在什么问题? Java SE文章参考:Java SE入门及基础知识合集-CSDN博客 方法带参 1. 构造方法带参 …...

蓝桥杯回文日期判断
思想:对于回文数的判断方法,最快的就是取其中一半的字符串长度,为s,然后将其进行翻转为s’ ,再把两者进行拼接即可保证是回文数,这样子就解决了枚举所有回文数的问题。 注意点: 要求必须是有效…...

Qt文件和目录相关操作
1.相关说明 QCoreApplication类、QFile类、QDir、QTemporaryDir类、QTemporaryFile类、QFileSystemWatcher类的相关函数 2.相关界面 3.相关代码 #include "dialog.h" #include "ui_dialog.h" #include <QFileDialog> #include <QTemporaryDir>…...

递归、搜索与回溯算法(专题一:递归)
往期文章(希望小伙伴们在看这篇文章之前,看一下往期文章) (1)递归、搜索与回溯算法(专题零:解释回溯算法中涉及到的名词)【回溯算法入门必看】-CSDN博客 接下来我会用几道题&#…...

element-ui 打包流程源码解析(下)
目录 目录结构和使用1,npm 安装1.1,完整引入1.2,按需引入 2,CDN3,国际化 接上文:element-ui 打包流程源码解析(上) 文章中提到的【上文】都指它 ↑ 目录结构和使用 我们从使用方式来…...

ChatGPT给出的前端面试考点(Vue.js)
ChatGPT给出的前端面试考点(Vue.js) 答案 1. Vue.js是什么?它的主要特点是什么? Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它的主要特点包括: 数据绑定:Vue.js使用双向数据绑定&…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...