GORM 是 Go 语言中一个非常流行的 ORM(Object-Relational Mapping)库,它简化了数据库操作,通过提供一套友好的 API,使开发者能够方便地进行数据库的创建、查询、更新和删除(CRUD)操作。本文将记录我学习 GORM 的过程,重点介绍如何使用 GORM 连接数据库并实现基本的增删改查功能。
一、环境准备
在开始使用 GORM 之前,我们需要确保我们的开发环境已准备好,以下是我的基本环境:
- Go 开发环境:首先需要在机器上安装 Go,并且确保
GOPATH和GOROOT配置正确。 - 数据库:本文使用 MySQL 作为数据库。确保 MySQL 已经安装并正在运行,并且能够访问。
二、初始化项目
我从创建一个新的 Go 项目开始:
mkdir gorm-crud-example
cd gorm-crud-example
在项目目录下,我会初始化一个 Go 模块:
go mod init gorm-crud-example
三、安装 GORM
接下来,我需要安装 GORM 和 MySQL 驱动。使用以下命令来获取所需的库:
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
这两个命令分别安装了 GORM 的核心库和 MySQL 驱动。
四、连接数据库
在学习 GORM 时,首先需要与数据库建立连接。我在 main.go 文件中添加了以下代码来进行数据库连接:
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
func main() {
// 数据库连接字符串:用户名:密码@tcp(主机:端口)/数据库名?charset=utf8mb4&parseTime=True&loc=Local
dsn := "username:password@tcp(127.0.0.1:3306)/gorm_example?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
log.Println("数据库连接成功")
}
在代码中,dsn 是数据库连接字符串,我需要根据实际的数据库配置修改 username、password 和 dbname。这里用的是 MySQL,端口是默认的 3306。
五、定义模型
GORM 通过结构体模型来映射数据库表。在这个例子中,我定义了一个简单的 User 模型:
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string `gorm:"uniqueIndex"`
Age uint8
CreatedAt time.Time
UpdatedAt time.Time
}
这里我定义了用户模型 User,它包含了 ID、Name、Email、Age、CreatedAt 和 UpdatedAt 字段,字段的标签(tag)用来告诉 GORM 如何映射到数据库列。
六、自动迁移
GORM 提供了自动迁移功能,可以根据模型结构自动创建或更新数据库表。下面的代码展示了如何使用 GORM 实现自动迁移:
func main() {
// 数据库连接代码省略
// 自动迁移
err := db.AutoMigrate(&User{})
if err != nil {
log.Fatalf("自动迁移失败: %v", err)
}
log.Println("自动迁移成功")
}
在调用 AutoMigrate 时,GORM 会检查数据库中是否存在 User 表,如果没有则会自动创建。如果已有该表,GORM 会检查字段是否匹配,并根据需要进行更新。
七、实现增删改查操作
1. 创建(Create)
我首先尝试了如何使用 GORM 创建一个新用户:
user := User{Name: "Alice", Email: "alice@example.com", Age: 25}
result := db.Create(&user)
if result.Error != nil {
log.Fatalf("创建用户失败: %v", result.Error)
}
log.Printf("创建用户成功: %v", user)
这里我通过 db.Create() 方法将 User 实例插入到数据库中,result 包含了执行操作的结果。如果创建成功,返回的 user 对象将会包含自动生成的 ID。
2. 查询(Read)
(1)根据主键查询
var user User
result := db.First(&user, 1) // 根据主键查询 ID 为 1 的用户
if result.Error != nil {
log.Fatalf("查询用户失败: %v", result.Error)
}
log.Printf("查询用户成功: %v", user)
使用 db.First() 方法根据主键(ID)查询用户。
(2)根据条件查询
var users []User
result := db.Where("age > ?", 20).Find(&users)
if result.Error != nil {
log.Fatalf("查询用户失败: %v", result.Error)
}
log.Printf("查询用户成功: %v", users)
通过 db.Where() 方法,我可以根据特定条件查询用户。在这个例子中,我查询了所有年龄大于 20 岁的用户。
3. 更新(Update)
(1)更新单个字段
result := db.Model(&user).Update("Age", 26)
if result.Error != nil {
log.Fatalf("更新用户失败: %v", result.Error)
}
log.Println("更新用户年龄成功")
使用 db.Model() 和 Update() 方法可以更新指定字段。在这个例子中,我更新了用户的 Age 字段。
(2)更新多个字段
result := db.Model(&user).Updates(User{Name: "Alice Smith", Age: 27})
if result.Error != nil {
log.Fatalf("更新用户失败: %v", result.Error)
}
log.Println("更新用户信息成功")
如果要更新多个字段,可以直接传递一个结构体给 Updates() 方法。
4. 删除(Delete)
result := db.Delete(&user)
if result.Error != nil {
log.Fatalf("删除用户失败: %v", result.Error)
}
log.Println("删除用户成功")
使用 db.Delete() 删除指定的记录。在这里,我删除了一个用户。
八、完整代码
将前面的代码整合在一起,完整的 main.go 文件如下:
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"time"
)
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string `gorm:"uniqueIndex"`
Age uint8
CreatedAt time.Time
UpdatedAt time.Time
}
func main() {
dsn := "username:password@tcp(127.0.0.1:3306)/gorm_example?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
log.Println("数据库连接成功")
// 自动迁移
err = db.AutoMigrate(&User{})
if err != nil {
log.Fatalf("自动迁移失败: %v", err)
}
log.Println("自动迁移成功")
// 创建用户
user := User{Name: "Alice", Email: "alice@example.com", Age: 25}
result := db.Create(&user)
if result.Error != nil {
log.Fatalf("创建用户失败: %v", result.Error)
}
log.Printf("创建用户成功: %v", user)
// 查询用户
var queryUser User
result = db.First(&queryUser, user.ID)
if result.Error != nil {
log.Fatalf("查询用户失败: %v", result.Error)
}
log.Printf("查询用户成功: %v", queryUser)
// 更新用户
result = db.Model(&queryUser).Updates(User{Name: "Alice Smith", Age: 27})
if result.Error != nil {
log.Fatalf("更新用户失败: %v", result.Error)
}
log.Println("更新用户信息成功")
// 删除用户
result = db.Delete(&queryUser)
if result.Error != nil {
log.Fatalf("删除用户失败: %v", result.Error)
}
log.Println("删除用户成功")
}
九、运行程序
确保数据库已经启动,并且在代码中正确配置了数据库连接信息。在项目目录下运行以下命令来启动程序:
go run main.go
一切正常,可以看到日志输出,表示各项操作成功执行。
十、总结
我们可以使用 GORM 来连接数据库,并实现了增删改查的基本功能。 希望我分享的这篇学习笔记能帮助到有需要的人。