数据库 | 豆包MarsCode AI刷题

91 阅读4分钟

GORM 是 Go 语言中最受欢迎的 ORM(对象关系映射)库之一,它提供了一个简单且高效的方式来操作数据库。GORM 支持多种数据库,包括 MySQL、PostgreSQL、SQLite、SQL Server 等,能够让开发者以结构体的方式与数据库进行交互,免去了手动编写 SQL 的麻烦。

本文将介绍如何使用 GORM 连接数据库,并实现增、删、改、查(CRUD)操作。

环境准备

在开始之前,你需要确保以下环境准备就绪:

  1. 安装 Go 语言(建议使用 Go 1.18 或更高版本)。
  2. 安装并配置好你选择的数据库(例如 MySQL、PostgreSQL 等)。
  3. 安装 GORM 库。

你可以通过以下命令安装 GORM:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql  # 以 MySQL 为例

配置数据库连接

在使用 GORM 之前,首先需要连接到数据库。这里以 MySQL 为例,我们将使用 GORM 提供的 gorm.io/driver/mysql 驱动来连接 MySQL。

package main

import (
	"fmt"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB
var err error

// 初始化数据库连接
func InitDB() {
	dsn := "user:password@tcp(localhost:3306)/dbname?charset=utf8&parseTime=True&loc=Local"
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatalf("数据库连接失败: %v", err)
	}
	fmt.Println("数据库连接成功")
}

func main() {
	InitDB()
}

说明

  • dsn 是数据库连接字符串,包含用户名、密码、主机地址、端口号、数据库名称等信息。
  • gorm.Open 函数用于打开数据库连接。

定义模型

在 GORM 中,你通过定义 Go 结构体来映射数据库表。每个结构体字段对应数据库中的一列,结构体的类型则对应字段的类型。你还可以通过标签(tags)来控制字段在数据库中的映射关系。

以一个简单的 User 表为例:

type User struct {
	ID        uint   `gorm:"primaryKey"`
	Name      string `gorm:"size:100"`
	Email     string `gorm:"uniqueIndex;size:100"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

说明

  • ID 字段是主键,GORM 会自动为其生成增量 ID。
  • Name 和 Email 分别是用户的姓名和邮箱,Email 设置了唯一索引。
  • CreatedAt 和 UpdatedAt 是 GORM 提供的内置时间戳字段,用来记录创建和更新时间。

自动迁移

GORM 提供了自动迁移功能,通过 AutoMigrate 函数可以根据结构体自动创建或更新数据库表。它会检查结构体字段的变化,并更新数据库表的结构。

func MigrateDB() {
	err := DB.AutoMigrate(&User{})
	if err != nil {
		log.Fatalf("表迁移失败: %v", err)
	}
	fmt.Println("表迁移成功")
}

func main() {
	InitDB()
	MigrateDB()
}

说明

  • AutoMigrate 会根据模型自动创建表,如果表已存在,则会自动更新表结构。

增加数据(Create)

GORM 提供了简单的增数据方法。你可以直接使用 Create 函数将数据插入到数据库中。

func CreateUser() {
	user := User{
		Name:  "John Doe",
		Email: "john.doe@example.com",
	}

	result := DB.Create(&user) // 传入结构体指针
	if result.Error != nil {
		log.Fatalf("数据插入失败: %v", result.Error)
	}
	fmt.Println("用户创建成功", user.ID)
}

func main() {
	InitDB()
	MigrateDB()
	CreateUser()
}

说明

  • Create 函数会插入一条新的记录。结构体中的字段会自动映射为数据库中的列。
  • user.ID 会自动生成并返回,GORM 会根据模型中的 ID 字段设置为主键,并自动生成值。

查询数据(Read)

GORM 支持多种查询方式,包括简单的查找、条件查询、关联查询等。

查询单条数据

通过 FirstFind 方法可以查询数据库中的数据:

func GetUser() {
	var user User
	result := DB.First(&user, 1) // 查询 ID 为 1 的用户
	if result.Error != nil {
		log.Fatalf("查询失败: %v", result.Error)
	}
	fmt.Printf("用户信息: %+v\n", user)
}

func main() {
	InitDB()
	MigrateDB()
	GetUser()
}

说明

  • First 会返回符合条件的第一条记录(按主键排序)。
  • Find 会返回所有符合条件的记录。

查询带条件的数据

你可以通过链式调用方法来构造复杂的查询条件:

func GetUsersByEmail() {
	var users []User
	result := DB.Where("email = ?", "john.doe@example.com").Find(&users)
	if result.Error != nil {
		log.Fatalf("查询失败: %v", result.Error)
	}
	fmt.Printf("查询结果: %+v\n", users)
}

func main() {
	InitDB()
	MigrateDB()
	GetUsersByEmail()
}

说明

  • Where 方法用于添加查询条件,Find 会返回符合条件的所有记录。

更新数据(Update)

GORM 提供了 SaveUpdates 方法来更新记录。

更新单个字段

func UpdateUser() {
	var user User
	result := DB.First(&user, 1)
	if result.Error != nil {
		log.Fatalf("查询失败: %v", result.Error)
	}

	user.Name = "Jane Doe"
	DB.Save(&user) // 更新单个字段

	fmt.Println("用户信息更新成功", user)
}

func main() {
	InitDB()
	MigrateDB()
	UpdateUser()
}

说明

  • Save 会更新所有字段,包括主键。
  • 如果你只想更新某些字段,可以使用 Updates 方法。

更新多个字段

func UpdateUserFields() {
	var user User
	result := DB.First(&user, 1)
	if result.Error != nil {
		log.Fatalf("查询失败: %v", result.Error)
	}

	DB.Model(&user).Updates(User{Name: "Alice", Email: "alice@example.com"})
	fmt.Println("多个字段更新成功", user)
}

func main() {
	InitDB()
	MigrateDB()
	UpdateUserFields()
}

说明

  • Model 用来指定要更新的记录,Updates 用来指定更新的字段。

删除数据(Delete)

删除数据非常简单,可以通过 Delete 方法来删除记录。

func DeleteUser() {
	var user User
	result := DB.First(&user, 1)
	if result.Error != nil {
		log.Fatalf("查询失败: %v", result.Error)
	}

	DB.Delete(&user)
	fmt.Println("用户删除成功")
}

func main() {
	InitDB()
	MigrateDB()
	DeleteUser()
}

说明

  • Delete 会根据主键删除记录。

总结

GORM 是一个功能强大的 ORM 库,它使得在 Go 中进行数据库操作变得非常简单和直观。本文介绍了如何使用 GORM 连接数据库,并实现了常见的增、删、改、查(CRUD)操作。通过 GORM,你可以轻松地操作数据库,而无需编写复杂的 SQL 语句。