对象关系映射
1. GORM 简介
GORM 是 Go 语言中一个功能强大的对象关系映射(ORM)库,支持多种数据库类型如 MySQL、PostgreSQL、SQLite 和 SQL Server。它提供了丰富的功能,包括模型定义、CRUD 操作、关联关系、事务处理等
主要特性:
- 全自动的 ORM 功能:支持结构体与数据库表的自动映射
- 丰富的查询构造器:支持链式调用构造查询
- 强大的迁移工具:支持数据库表的自动创建、更新和删除
- 灵活的钩子函数:允许在 CRUD 操作的不同阶段执行自定义逻辑1
2. 安装与连接数据库
安装 GORM
go go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql // 根据使用的数据库选择相应驱动
连接数据库
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
func main() {
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(err)
}
// 使用 db 进行数据库操作
}
3. 模型定义
基本模型
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:255"`
Email string `gorm:"uniqueIndex"`
CreatedAt time.Time
UpdatedAt time.Time
}
使用 gorm.Model
type User struct {
gorm.Model // 包含 ID, CreatedAt, UpdatedAt, DeletedAt 字段
Name string
}
自定义表名和列名
func (User) TableName() string {
return "users"
}
type User struct {
ID uint `gorm:"column:user_id"`
// 其他字段...
}
4. 基本 CRUD 操作
创建记录
user := User{Name: "John", Email: "john@example.com"}
result := db.Create(&user)
if result.Error != nil {
log.Fatal(result.Error)
}
查询记录
// 查询第一条记录
var user User
db.First(&user)
// 根据主键查询
db.First(&user, 1)
// 条件查询
db.Where("name = ?", "John").First(&user)
// 查询所有记录
var users []User
db.Find(&users)
更新记录
// 更新单个字段
db.Model(&user).Update("Name", "Jane")
// 更新多个字段
db.Model(&user).Updates(User{Name: "Jane", Email: "jane@example.com"})
删除记录
db.Delete(&user)
5. 高级特性
关联关系
GORM 支持多种关联关系:
- Has One (一对一)
- Has Many (一对多)
- Belongs To (从属)
- Many To Many (多对多)
事务处理
tx := db.Begin()
if err := tx.Create(&user).Error; err != nil {
tx.Rollback()
return err
}
tx.Commit()
钩子函数
GORM 提供多种钩子函数,如:
- BeforeCreate / AfterCreate
- BeforeSave / AfterSave
- BeforeUpdate / AfterUpdate
- BeforeDelete / AfterDelete3
预加载
db.Preload("Profile").First(&user)
6. 自动迁移
db.AutoMigrate(&User{})
7. 性能优化建议
- 批量插入使用
CreateInBatches
- 使用
Select
和Omit
控制写入字段 - 合理使用预加载避免 N+1 查询问题
8. 常见问题与解决方案
- 时间处理:确保 DSN 中包含
parseTime=true
- 字符编码:使用
charset=utf8mb4
支持完整 UTF-8 - 字段权限控制:通过标签控制字段的读写权限
9. 完整示例
package main
import (
"fmt"
"log"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint
Name string
Email string
CreatedAt time.Time
}
func main() {
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(err)
}
// 自动迁移
db.AutoMigrate(&User{})
// 创建记录
user := User{Name: "Alice", Email: "alice@example.com"}
db.Create(&user)
// 查询记录
var result User
db.First(&result, user.ID)
fmt.Printf("User: %+v\n", result)
}