Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Gin 介绍
  • Gin 环境搭建
  • golang 程序的热加载
  • Gin 框架中的路由
  • Gin HTML 模板渲染
  • 静态文件服务
  • 路由详解
  • Gin 中自定义控制器
  • Gin 中间件
  • Gin 中自定义 Model
  • Gin 文件上传
  • Gin 中的 Cookie
  • Gin 中的 Session
  • Gin 中使用 GORM 操作 mysql 数据库
    • 1、GORM 简单介绍
    • 2、Gin 中使用 GORM
    • 3、Gin GORM CURD
      • 3.1、增加
      • 3.2、查找
      • 3.3、修改
      • 3.4、删除
      • 3.5、批量删除
    • 4、Gin GORM 查询语句详解
      • 4.1、Where
      • 4.2、Or 条件
      • 4.3、选择字段查询
      • 4.4、排序 Limit 、Offset
      • 4.5、获取总数
      • 4.6、Distinct
      • 4.7、Scan
      • 4.8、Join (先了解 后面课程会讲关联查询)
    • 5、Gin GORM 查看执行的 sql
  • 原生 SQL 和 SQL 生成器
  • Gin 中使用 GORM 实现表关联查询
  • GORM 中使用事务
  • Gin 中使用 go-ini 加载.ini 配置文件
  • 《Gin》笔记
Salmon
2025-04-05
目录

Gin 中使用 GORM 操作 mysql 数据库

# 1、GORM 简单介绍

GORM 是 Golang 的一个 orm 框架。简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping) 的缩写。使用 ORM 框架可以让我们更方便的操作数据库。

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

image-20250407233104277

Gorm 特性

  • 全功能 ORM

  • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承) • Create,Save,Update,Delete,Find 中钩子方法

  • 支持 Preload、Joins 的预加载

  • 事务,嵌套事务,Save Point,Rollback To Saved Point • Context、预编译模式、DryRun 模式

  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD

  • SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询

  • 复合主键,索引,约束

  • Auto Migration

  • 自定义 Logger • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…

  • 每个特性都经过了测试的重重考验

  • 开发者友好

官方文档:https://gorm.io/zh_CN/docs/index.html (opens new window)

# 2、Gin 中使用 GORM

1、安装

如果使用 go mod 管理项目的话可以忽略此步骤

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

2、Gin 中使用 Gorm 连接数据库

在 models 下面新建 core.go ,建立数据库链接

package models

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
)

var DB *gorm.DB
var err error

func Init() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("数据库连接失败:", err)
	}
	// 自动创建表
	err = DB.AutoMigrate(&User{})
	if err != nil {
		log.Fatal("自动建表失败:", err)
	}
	log.Println("数据库表已创建或同步成功")
}

3、定义操作数据库的模型

Gorm 官方给我们提供了详细的:https://gorm.io/zh_CN/docs/models.html (opens new window)

虽然在 gorm 中可以指定字段的类型以及自动生成数据表,但是在实际的项目开发中,我们是先设计数据库表,然后去实现编码的。

在实际项目中定义数据库模型注意以下几点:

1、结构体的名称必须首字母大写 ,并和数据库表名称对应。例如:表名称为 user 结构体名称定义成 User,表名称为 article_cate 结构体名称定义成 ArticleCate

2、结构体中的字段名称首字母必须大写,并和数据库表中的字段一一对应。例如:下面结构体中的 Id 和数据库中的 id 对应,Username 和数据库中的 username 对应,Age 和数据库中的 age 对应,Email 和数据库中的 email 对应,AddTime 和数据库中的 add_time 字段对应

3、默认情况表名是结构体名称的复数形式。如果我们的结构体名称定义成 User,表示这个模型默认操作的是 users 表。

4、我们可以使用结构体中的自定义方法 TableName 改变结构体的默认表名称,如下:

func (User) TableName() string {
    return "user"
}

表示把 User 结构体默认操作的表改为 user 表

定义 user 模型:

package models

// User 默认表名是 `users`
type User struct {
	Id       int    `gorm:"primaryKey;autoIncrement"` // ID,主键
	Username string `gorm:"size:50;not null;unique" form:"username" json:"username"`  // 用户名,唯一
	Age      int    `form:"age" json:"age"` // 年龄
	Email    string `gorm:"size:100" form:"email" json:"email"` // 邮箱地址
	AddTime  int    // 添加时间(Unix 时间戳)
}

func (User) TableName() string {
	return "user"
}

关于更多模型定义的方法参考:https://gorm.io/zh_CN/docs/conventions.html (opens new window)

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt

// gorm.Model 的定义
type Model struct {
    ID uint `gorm:"primaryKey"` 
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt `gorm:"index"` 
}

# 3、Gin GORM CURD

找到要操作数据库表的控制器,然后引入 models 模块

# 3.1、增加

增加成功后会返回刚才增加的记录

func (con UserController) Add(c *gin.Context) {
	var user models.User

	// 绑定参数(form、query 等)
	if err := c.ShouldBind(&user); err != nil {
		c.String(http.StatusBadRequest, "参数绑定失败: %v", err)
		return
	}
	//user := models.User{
	//	Username: "王五", Age: 18, Email: "1179732961@qq.com", AddTime: int(time.Now().Unix())}
	result := models.DB.Create(&user) // 通过数据的指针来创建
	if result.RowsAffected > 1 {
		fmt.Print(user.Id)
	}
	fmt.Println(result.RowsAffected)
	fmt.Println(user.Id)
	c.String(http.StatusOK, "添加成功,ID: %d", user.Id)
}

更多增加语句:https://gorm.io/zh_CN/docs/create.html (opens new window)

# 3.2、查找

查找全部

func (con UserController) SelectAll(c *gin.Context) {
    user := []models.User{}
    models.DB.Find(&user)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": user})
}

指定条件查找

func (con UserController) QueryByParam(c *gin.Context) {
    user := []models.User{}
    models.DB.Where("username=?", "王五").Find(&user)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": user})
}

更多查询语句:https://gorm.io/zh_CN/docs/query.html (opens new window)

# 3.3、修改

func (con UserController) Edit(c *gin.Context) {
    user := models.User{Id: 7}
    models.DB.Find(&user)
    user.Username = "gin gorm"
    user.Age = 1
    models.DB.Save(&user)
    c.String(http.StatusOK, "Edit")
}

更多修改的方法参考:https://gorm.io/zh_CN/docs/update.html (opens new window)

# 3.4、删除

func (con UserController) Delete(c *gin.Context) {
    user := models.User{Id: 8}
    models.DB.Delete(&user)
    c.String(http.StatusOK, "Delete")
}

更多删除的方法参考:https://gorm.io/zh_CN/docs/delete.html (opens new window)

# 3.5、批量删除

db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
// DELETE from emails where email LIKE "%jinzhu%";
db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
// DELETE from emails where email LIKE "%jinzhu%";
func (con UserController) DeleteAll(c *gin.Context) {
    user := models.User{}
    models.DB.Where("id>9").Delete(&user)
    c.String(http.StatusOK, "DeleteAll")
}

更多删除的方法参考:https://gorm.io/zh_CN/docs/delete.html (opens new window)

# 4、Gin GORM 查询语句详解

官方文档:https://gorm.io/zh_CN/docs/query.html (opens new window)

# 4.1、Where

  • =

  • <

    nav := []models.Nav{}
    models.DB.Where("id<3").Find(&nav)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": nav})
    
  • >

    var n = 5
    nav := []models.Nav{}
    models.DB.Where("id>?", n).Find(&nav)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": nav})
    
  • <=

  • >=

  • !=

  • IS NOT NULL

  • IS NULL

  • BETWEEN AND

    nav := []models.Nav{}
    models.DB.Where("id between ? and ?", 3, 6).Find(&nav)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": nav})
    
  • NOT BETWEEN AND

  • IN

    nav := []models.Nav{}
    models.DB.Where("id in (?)", []int{3, 5, 6}).Find(&nav)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": nav})
    
  • OR

  • AND

    var n1 = 3
    var n2 = 9
    nav := []models.Nav{}
    models.DB.Where("id > ? AND id < ?", n1, n2).Find(&nav)
    c.JSON(http.StatusOK, gin.H{ "success": true, "result": nav})
    
  • NOT

  • LIKE

    nav := []models.Nav{}
    models.DB.Where("title like ?", "%会%").Find(&nav)
    c.JSON(http.StatusOK, gin.H{"success": true, "result": nav})
    

# 4.2、Or 条件

nav := []models.Nav{}
models.DB.Where("id=? OR id=?", 2, 3).Find(&nav)

或者

nav := []models.Nav{}
models.DB.Where("id=?", 2).Or("id=?", 3).Or("id=4").Find(&nav)

# 4.3、选择字段查询

nav := []models.Nav{}
models.DB.Select("id, title,url").Find(&nav)

# 4.4、排序 Limit 、Offset

nav := []models.Nav{}
models.DB.Where("id>2").Order("id Asc").Find(&nav)
nav := []models.Nav{}
models.DB.Where("id>2").Order("sort Desc").Order("id Asc").Find(&nav)
nav := []models.Nav{}
models.DB.Where("id>1").Limit(2).Find(&nav)

跳过 2 条查询 2 条

nav := []models.Nav{}
models.DB.Where("id>1").Offset(2).Limit(2).Find(&nav)

# 4.5、获取总数

nav := []models.Nav{}
var num int64
models.DB.Where("id > ?", 2).Find(&nav).Count(&num)

# 4.6、Distinct

从模型中选择不相同的值

nav := []models.Nav{}
models.DB.Distinct("title").Order("id desc").Find(&nav)
c.JSON(200, gin.H{ "nav": nav, })

等价SQL

SELECT DISTINCT `title` FROM `nav` ORDER BY id desc

# 4.7、Scan

type Result struct {
    Name string
    Age int
}

var result Result
db.Table("users").Select("name", "age").Where("name = ?", "Antonio").Scan(&result)

// 原生 SQL
db.Raw("SELECT name, age FROM users WHERE name = ?", "Antonio").Scan(&result)

var result []models.User
models.DB.Raw("SELECT * FROM user").Scan(&result)
fmt.Println(result)

# 4.8、Join (先了解 后面课程会讲关联查询)

type result struct {
    Name string
    Email string
}
db.Model(&User{}).Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&result{})

等同SQL

SELECT users.name, emails.email FROM `users` left join emails on emails.user_id = users.id

# 5、Gin GORM 查看执行的 sql

package models

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
    "log"
)

var DB *gorm.DB
var err error

func Init() {
    dsn := "root:123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
       QueryFields: true,                                // 查询语句中会显式列出所有字段名
       Logger:      logger.Default.LogMode(logger.Info), // 打印完整 SQL
    })
    if err != nil {
       log.Fatal("数据库连接失败:", err)
    }
    // 自动创建表
    err = DB.AutoMigrate(&User{})
    if err != nil {
       log.Fatal("自动建表失败:", err)
    }
    log.Println("数据库表已创建或同步成功")
    //DB.Debug() 临时打印执行sql
}

效果如下:

image-20250409003624484

上次更新: 2025/04/09, 00:59:06
Gin 中的 Session
原生 SQL 和 SQL 生成器

← Gin 中的 Session 原生 SQL 和 SQL 生成器→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式