13-Gin 中使用 GORM 操作 mysql 数据库 --[Gin 框架入门精讲与实战案例]

GORM 简单介绍

GORM(Golang ORM)是Go语言(Golang)中一个非常流行的对象关系映射(ORM)库,它旨在简化数据库操作。通过GORM,开发者可以使用结构体和接口来代替SQL语句进行数据库的增删改查等操作,从而提高开发效率并减少错误。

GORM 的主要特点

  1. 支持多种数据库:GORM 支持 MySQL、PostgreSQL、SQLite3、SQL Server 等多种主流的关系型数据库。
  2. 自动迁移:GORM 可以根据结构体定义自动生成或更新数据库表结构。
  3. 关联管理:支持一对多、多对多等复杂的数据模型关联关系,并提供便捷的方法来操作这些关联。
  4. 预加载:可以预先加载相关联的数据,减少 N+1 查询问题。
  5. 事务处理:内置对事务的支持,确保数据的一致性和完整性。
  6. 钩子函数:允许在创建、更新、删除记录前后执行自定义逻辑。
  7. 插件系统:拥有丰富的插件生态系统,方便扩展功能。

安装 GORM

要开始使用 GORM,首先需要安装它。你可以通过 go get 命令来安装:

bash 复制代码
go get -u gorm.io/gorm

此外,还需要安装对应数据库驱动,例如对于 PostgreSQL:

bash 复制代码
go get -u gorm.io/driver/postgres

基本用法示例

下面是一个简单的例子,展示如何连接到数据库以及基本的CRUD操作:

导入包
go 复制代码
import (
  "gorm.io/driver/sqlite"
  "gorm.io/gorm"
)
连接到数据库
go 复制代码
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
  panic("failed to connect database")
}
定义模型
go 复制代码
type Product struct {
  gorm.Model
  Code  string
  Price uint
}
自动迁移
go 复制代码
db.AutoMigrate(&Product{})
创建记录
go 复制代码
db.Create(&Product{Code: "D42", Price: 100})
查询记录
go 复制代码
var product Product
db.First(&product, 1) // 根据主键查询第一条记录
db.First(&product, "code = ?", "D42") // 根据条件查询第一条记录
更新记录
go 复制代码
db.Model(&product).Update("Price", 200)
删除记录
go 复制代码
db.Delete(&product, 1) // 根据主键删除记录

总结

GORM 是一个强大且易于使用的 ORM 库,它为 Go 开发者提供了高效的数据库交互方式。通过其简洁的 API 和灵活的功能,可以大大简化应用程序中的数据持久化层代码编写。如果你正在寻找一种方法来快速构建基于 Go 的应用,并且希望避免直接编写复杂的 SQL 语句,那么 GORM 可能正是你需要的工具。

Gin 中使用 GORM

在 Gin 框架中使用 GORM 来操作 MySQL 数据库,首先你需要确保安装了必要的依赖包,并配置好数据库连接。下面我将指导你如何设置和使用 GORM 连接 MySQL 数据库。

1. 安装依赖

首先,确保你的项目中包含了 Gin 和 GORM 的 MySQL 驱动。你可以通过以下命令来安装这些依赖:

bash 复制代码
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

2. 配置数据库连接

接下来,在你的 Go 程序中配置 MySQL 数据库的连接。这通常包括设置数据库 URL 和初始化 GORM。

示例代码 (main.go)
go 复制代码
package main

import (
	"fmt"
	"log"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// Product 是一个示例模型
type Product struct {
	gorm.Model
	Code  string
	Price uint
}

func main() {
	// MySQL 数据库连接字符串
	dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

	// 打开数据库连接
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("failed to connect database")
	}

	// 自动迁移表结构
	db.AutoMigrate(&Product{})

	// 创建 Gin 路由器
	router := gin.Default()

	// 设置路由处理函数
	router.GET("/products", func(c *gin.Context) {
		var products []Product
		if result := db.Find(&products); result.Error != nil {
			c.JSON(500, gin.H{"error": "无法获取产品列表"})
			return
		}
		c.JSON(200, products)
	})

	router.POST("/products", func(c *gin.Context) {
		var product Product
		if err := c.ShouldBindJSON(&product); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}
		if result := db.Create(&product); result.Error != nil {
			c.JSON(500, gin.H{"error": "创建产品失败"})
			return
		}
		c.JSON(201, product)
	})

	// 启动服务器
	if err := router.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}

3. 数据库连接字符串

在上面的代码中,dsn 变量包含了 MySQL 数据库的连接字符串。格式如下:

plaintext 复制代码
user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
  • user:MySQL 用户名。
  • password:MySQL 密码。
  • 127.0.0.1:3306:MySQL 服务器地址和端口(默认为 3306)。
  • dbname:要连接的数据库名称。
  • charset=utf8mb4&parseTime=True&loc=Local:一些额外的参数,用于指定字符集、时间解析和时区。

请根据实际情况修改这些值以匹配你的 MySQL 配置。

4. 测试 API

启动应用程序后,你可以使用工具如 Postman 或 curl 来测试定义的 API 端点。例如,向 /products 发送 GET 请求以获取所有产品的列表,或者发送 POST 请求并附带 JSON 数据来创建新产品。

总结

通过上述步骤,你已经成功地在 Gin 框架中集成了 GORM 并连接到了 MySQL 数据库。这个基础设置可以帮助你快速开始构建基于 RESTful API 的 Web 应用程序。

Gin GORM CURD

在 Gin 框架中使用 GORM 进行 MySQL 数据库的 CRUD(创建、读取、更新、删除)操作,可以通过定义模型结构体并编写相应的路由处理函数来实现。下面我将详细说明如何完成这些操作,并提供完整的代码示例。

1. 安装依赖

首先,确保你的项目中包含了 Gin 和 GORM 的 MySQL 驱动。你可以通过以下命令来安装这些依赖:

bash 复制代码
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

2. 配置数据库连接和初始化

接下来,在你的 Go 程序中配置 MySQL 数据库的连接,并初始化 GORM。

示例代码 (main.go)
go 复制代码
package main

import (
	"fmt"
	"log"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// Product 是一个示例模型
type Product struct {
	gorm.Model
	Code  string `json:"code" gorm:"unique"`
	Price uint   `json:"price"`
}

var db *gorm.DB

func init() {
	// MySQL 数据库连接字符串
	dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

	var err error
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("failed to connect database")
	}

	// 自动迁移表结构
	db.AutoMigrate(&Product{})
}

func main() {
	// 创建 Gin 路由器
	router := gin.Default()

	// 设置路由处理函数
	router.GET("/products", GetProducts)
	router.GET("/products/:id", GetProduct)
	router.POST("/products", CreateProduct)
	router.PUT("/products/:id", UpdateProduct)
	router.DELETE("/products/:id", DeleteProduct)

	// 启动服务器
	if err := router.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}

3. 实现 CRUD 操作

现在我们为每个 CRUD 操作定义对应的处理函数。

获取所有产品 (GetProducts)
go 复制代码
func GetProducts(c *gin.Context) {
	var products []Product
	if result := db.Find(&products); result.Error != nil {
		c.JSON(500, gin.H{"error": "无法获取产品列表"})
		return
	}
	c.JSON(200, products)
}
根据 ID 获取单个产品 (GetProduct)
go 复制代码
func GetProduct(c *gin.Context) {
	id := c.Param("id")
	var product Product
	if result := db.First(&product, id); result.Error != nil {
		c.JSON(404, gin.H{"error": "产品未找到"})
		return
	}
	c.JSON(200, product)
}
创建新产品 (CreateProduct)
go 复制代码
func CreateProduct(c *gin.Context) {
	var input Product
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}
	if result := db.Create(&input); result.Error != nil {
		c.JSON(500, gin.H{"error": "创建产品失败"})
		return
	}
	c.JSON(201, input)
}
更新现有产品 (UpdateProduct)
go 复制代码
func UpdateProduct(c *gin.Context) {
	id := c.Param("id")
	var product Product
	if result := db.First(&product, id); result.Error != nil {
		c.JSON(404, gin.H{"error": "产品未找到"})
		return
	}

	var input Product
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	product.Code = input.Code
	product.Price = input.Price

	db.Save(&product)
	c.JSON(200, product)
}
删除产品 (DeleteProduct)
go 复制代码
func DeleteProduct(c *gin.Context) {
	id := c.Param("id")
	var product Product
	if result := db.First(&product, id); result.Error != nil {
		c.JSON(404, gin.H{"error": "产品未找到"})
		return
	}

	if result := db.Delete(&product); result.Error != nil {
		c.JSON(500, gin.H{"error": "删除产品失败"})
		return
	}

	c.JSON(204, gin.H{"message": "产品已成功删除"})
}

4. 测试 API

启动应用程序后,你可以使用工具如 Postman 或 curl 来测试定义的 API 端点。例如:

  • GET /products:获取所有产品的列表。
  • GET /products/:id:根据 ID 获取单个产品。
  • POST /products :创建新产品,需附带 JSON 数据,如 { "code": "D42", "price": 100 }
  • PUT /products/:id :更新现有产品,需附带 JSON 数据,如 { "code": "D42", "price": 200 }
  • DELETE /products/:id:删除指定 ID 的产品。

总结

通过上述步骤,你已经实现了在 Gin 框架中使用 GORM 对 MySQL 数据库进行基本的 CRUD 操作。这个基础设置可以帮助你快速开始构建基于 RESTful API 的 Web 应用程序。

Gin GORM 查询语句详解

在 Gin 框架中使用 GORM 进行 MySQL 数据库查询时,GORM 提供了多种方法来构建和执行查询语句。这些方法既强大又灵活,能够满足从简单到复杂的各种查询需求。下面我将详细介绍一些常用的 GORM 查询方法,并给出具体的例子。

1. 基本查询

获取所有记录
go 复制代码
var products []Product
db.Find(&products) // 获取所有产品记录
根据主键获取单条记录
go 复制代码
var product Product
db.First(&product, 1) // 根据主键 ID = 1 获取第一条记录
根据条件获取单条记录
go 复制代码
db.Where("code = ?", "D42").First(&product) // 根据条件 code = 'D42' 获取第一条记录

2. 条件查询

你可以通过 Where 方法添加查询条件,支持多种类型的条件表达式。

等值查询
go 复制代码
db.Where("price > ?", 100).Find(&products) // 查找价格大于 100 的产品
多个条件
go 复制代码
db.Where("code = ? AND price > ?", "D42", 100).Find(&products)
使用结构体或 map 作为条件
go 复制代码
// 使用结构体
db.Where(&Product{Code: "D42", Price: 100}).Find(&products)

// 使用 map
db.Where(map[string]interface{}{"code": "D42", "price": 100}).Find(&products)
IN 查询
go 复制代码
db.Where("code IN ?", []string{"D42", "L42"}).Find(&products)
LIKE 查询
go 复制代码
db.Where("name LIKE ?", "%Apple%").Find(&products)

3. 排序与分页

排序
go 复制代码
db.Order("price desc").Find(&products) // 按价格降序排列
分页
go 复制代码
page := 1
pageSize := 10
db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&products)

4. 聚合查询

计数
go 复制代码
var count int64
db.Model(&Product{}).Count(&count) // 统计产品总数
求和
go 复制代码
var sum float64
db.Model(&Product{}).Select("sum(price)").Scan(&sum) // 求所有产品的价格总和

5. 关联查询

假设有一个 Order 模型,它关联了多个 Product

go 复制代码
type Order struct {
  gorm.Model
  Products []Product `gorm:"many2many:order_products;"`
}
预加载关联数据
go 复制代码
var order Order
db.Preload("Products").First(&order, 1) // 加载订单及其相关的产品

6. 自定义 SQL 查询

如果你需要更复杂的查询,可以直接使用原生 SQL:

go 复制代码
var result []Product
db.Raw("SELECT * FROM products WHERE price > ?", 100).Scan(&result)

7. 事务处理

对于需要保证原子性的操作,可以使用事务:

go 复制代码
tx := db.Begin()
defer func() {
  if r := recover(); r != nil {
    tx.Rollback()
  }
}()

if err := tx.Error; err != nil {
  return err
}

// 在事务中执行一系列数据库操作
if tx.Where("code = ?", "D42").Delete(&Product{}).Error != nil {
  tx.Rollback()
  return err
}

if tx.Create(&Product{Code: "D42", Price: 100}).Error != nil {
  tx.Rollback()
  return err
}

tx.Commit()

8. 使用回调函数

GORM 支持钩子(callbacks),可以在创建、更新或删除记录前后执行自定义逻辑:

go 复制代码
type Product struct {
  gorm.Model
  Code  string
  Price uint
}

func (p *Product) BeforeCreate(tx *gorm.DB) (err error) {
  p.Code = strings.ToUpper(p.Code) // 将代码转换为大写
  return
}

总结

以上就是一些常见的 GORM 查询语句及用法示例。GORM 提供了一套非常直观且强大的 API 来进行数据库查询,使得开发者可以专注于业务逻辑而不需要编写大量的 SQL 语句。当然,GORM 的功能远不止于此,还有许多高级特性等待你去探索。

相关推荐
明明跟你说过27 分钟前
MySQL 数据表与索引设计艺术:打造高效数据存取架构
数据库·mysql·database·big data
知识中的海王30 分钟前
【已解决】Django连接mysql报错Did you install mysqlclient?
python·mysql·django
迎风追日37 分钟前
时序数据库对比
数据库·时序数据库
TiDB_PingCAP1 小时前
Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
数据库·mysql·tidb
TiDB_PingCAP1 小时前
基于时间维度水平拆分的多 TiDB 集群统一数据路由/联邦查询技术的实践
数据库·分布式·tidb
睿思达DBA_WGX2 小时前
与 Oracle Dataguard 相关的进程及作用分析
数据库·oracle
睿思达DBA_WGX2 小时前
Oracle Dataguard(主库为单节点)配置详解(4):将主库复制到备库并启动同步
数据库·oracle
yuanbenshidiaos2 小时前
MYSQL--------事务控制和锁定语句
数据库·mysql
斗-匕2 小时前
MySQL执行计划分析
数据库·mysql
蜗牛_snail2 小时前
学习笔记 : MySQL进阶篇一之架构和日志文件
笔记·学习·mysql