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使用双向数据绑定&…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
