一、前言
前面31篇我们完成了 Go基础语法、并发、网络编程、Gin企业级高阶骨架。
真实后端项目 99% 都是:接口 + 数据库CURD。
本篇正式打通Gin + GORM + MySQL 完整链路,带你从零实现:
数据库连接、模型绑定、自动建表、增删改查、软删除、连接池配置、事务、简单工程分层。
所有代码复制即用、零报错、可直接用于项目开发。
二、核心知识点预告
GORM 是什么:Go 最主流 ORM 框架,替代原生 SQL,开发效率极高
MySQL 连接 + 连接池参数调优(生产必备)
结构体模型绑定数据表、自动迁移建表
完整 RESTful CRUD 接口:新增、查询、修改、删除
软删除实现(企业级标准,不真删数据)
GORM 事务操作(保证数据一致性)
简易工程分层:模型层、数据库层、接口层
三、环境依赖安装
GORM v2 是目前稳定主流版本,搭配 MySQL 驱动
# 安装GORM核心库
go get gorm.io/gorm
# 安装MySQL驱动
go get gorm.io/driver/mysql
四、GORM连接MySQL(生产级连接池配置)
1. 连接参数说明
原生连接容易出现连接泄露、连接超时、并发卡死,必须配置连接池。
2. 完整数据库初始化代码
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"time"
)
// 全局DB变量,项目全局复用
var DB *gorm.DB
// InitDB 初始化MySQL连接 + 连接池配置
func InitDB() {
// DSN格式:用户名:密码@tcp(127.0.0.1:3306)/数据库名?参数
dsn := "root:123456@tcp(127.0.0.1:3306)/go_gin_demo?charset=utf8mb4&parseTime=True&loc=Local"
// 打开连接
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
// 关闭默认日志,可开启查看SQL语句
// Logger: logger.Default.LogMode(logger.Info),
})
if err != nil {
log.Fatal("数据库连接失败:", err)
}
// 获取原生SQL DB对象,配置连接池
sqlDB, err := db.DB()
if err != nil {
log.Fatal("获取连接池失败:", err)
}
// 最大空闲连接数
sqlDB.SetMaxIdleConns(10)
// 最大打开连接数
sqlDB.SetMaxOpenConns(100)
// 连接最大存活时间
sqlDB.SetConnMaxLifetime(1 * time.Hour)
// 空闲连接超时时间
sqlDB.SetConnMaxIdleTime(30 * time.Minute)
DB = db
log.Println("MySQL连接成功!")
}
func main() {
// 初始化数据库
InitDB()
}
五、定义数据模型 & 自动建表
GORM 最大优势:结构体即数据表,无需手写SQL建表,自动迁移字段。
1. 用户模型(含软删除、自动时间戳)
package main
import (
"gorm.io/gorm"
"time"
)
// User 用户模型
// gorm.Model 自带:ID、CreatedAt、UpdatedAt、DeletedAt
type User struct {
gorm.Model
Username string `gorm:"size:32;not null;comment:用户名"`
Password string `gorm:"size:64;not null;comment:密码"`
Age int `gorm:"default:18;comment:年龄"`
Phone string `gorm:"size:11;comment:手机号"`
}
// AutoMigrate 自动建表/更新表结构
func AutoMigrate() {
err := DB.AutoMigrate(&User{})
if err != nil {
panic("表结构迁移失败:" + err.Error())
}
}
func main() {
InitDB()
// 自动创建或更新数据表
AutoMigrate()
}
运行后自动生成 users 数据表,自带主键、创建时间、更新时间、软删除标记。
六、Gin + GORM 完整CRUD接口实战
整合 Gin 路由 + GORM 数据库操作,实现企业级标准五套接口:新增、查询单条、查询列表、修改、删除
完整可运行CRUD代码
package main
import (
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"time"
)
var DB *gorm.DB
// User 用户模型
type User struct {
gorm.Model
Username string `gorm:"size:32;not null;comment:用户名"`
Password string `gorm:"size:64;not null;comment:密码"`
Age int `gorm:"default:18;comment:年龄"`
Phone string `gorm:"size:11;comment:手机号"`
}
// InitDB 初始化数据库
func InitDB() {
dsn := "root:123456@tcp(127.0.0.1:3306)/go_gin_demo?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("数据库连接失败:", err)
}
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(1 * time.Hour)
DB = db
}
// AutoMigrate 自动建表
func AutoMigrate() {
_ = DB.AutoMigrate(&User{})
}
func main() {
// 初始化
InitDB()
AutoMigrate()
r := gin.Default()
// 1. 新增用户
r.POST("/user/create", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"code": 400, "msg": "参数错误"})
return
}
// 数据库创建数据
DB.Create(&user)
c.JSON(200, gin.H{"code": 200, "msg": "创建成功", "data": user})
})
// 2. 根据ID查询单条用户
r.GET("/user/get/:id", func(c *gin.Context) {
id := c.Param("id")
var user User
DB.First(&user, id)
c.JSON(200, gin.H{"code": 200, "data": user})
})
// 3. 查询用户列表
r.GET("/user/list", func(c *gin.Context) {
var list []User
DB.Find(&list)
c.JSON(200, gin.H{"code": 200, "data": list})
})
// 4. 更新用户信息
r.POST("/user/update/:id", func(c *gin.Context) {
id := c.Param("id")
var user User
// 先查询
DB.First(&user, id)
// 绑定新参数
_ = c.ShouldBindJSON(&user)
// 保存更新
DB.Save(&user)
c.JSON(200, gin.H{"code": 200, "msg": "更新成功", "data": user})
})
// 5. 删除用户(软删除)
r.GET("/user/delete/:id", func(c *gin.Context) {
id := c.Param("id")
var user User
DB.Delete(&user, id)
c.JSON(200, gin.H{"code": 200, "msg": "删除成功(软删除)"})
})
_ = r.Run(":8080")
}
七、重点核心特性讲解
1. 软删除原理
模型内嵌gorm.Model 自带 DeletedAt 字段。
调用 DB.Delete()不会真正删除数据,只会给 DeletedAt 赋值时间戳。
普通查询 First/Find 会自动过滤已删除数据,企业项目标准用法。
2. 恢复已删除数据(了解)
// 恢复软删除数据
var user User
// Unscoped 查询包含已删除数据
DB.Unscoped().First(&user, id)
// 清空删除时间,恢复数据
DB.Model(&user).Update("deleted_at", nil)
3. 分页查询(高频业务)
// 分页:page页码,size每页条数
page := 1
size := 10
var list []User
var total int64
DB.Model(&User{}).Count(&total)
DB.Limit(size).Offset((page-1)*size).Find(&list)
八、GORM 事务实战(保证数据一致性)
涉及多表操作、连续写入、金额变动,必须使用事务,要么全部成功,要么全部回滚。
// TransactionDemo 事务示例
func TransactionDemo() error {
return DB.Transaction(func(tx *gorm.DB) error {
// 操作1:创建用户
user := User{Username: "事务测试", Password: "123456"}
tx.Create(&user)
// 模拟异常,测试回滚
// return errors.New("中断操作,事务回滚")
// 返回nil则提交事务
return nil
})
}
返回 nil 自动提交,返回 error 自动回滚,极简安全。
九、简易工程分层规范(企业雏形)
单文件仅适合学习,项目开发必须分层,标准结构:
model:存放所有数据模型
db:数据库初始化、公共方法
controller:接收接口参数、响应数据
service:业务逻辑处理
router:路由注册
十、本篇总结
掌握 GORM 连接 MySQL + 生产级连接池配置
理解结构体映射数据表、自动迁移建表机制
熟练使用 5 大基础 CURD 接口
掌握企业级软删除特性
掌握事务机制,解决数据一致性问题
具备 Gin+MySQL 完整后端开发能力
十一、下期预告
下一篇:Go语言入门33:Gin分层架构实战(路由分层、控制器分层、服务层分层、解耦重构完整版),彻底告别单文件代码,搭建企业标准化项目架构!