Golang GORM 库

对象关系映射

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)
}
滚动至顶部