GORM 详细教程

GORM 是 Go 语言中最流行的 ORM (对象关系映射) 库之一,提供了强大的数据库操作功能。本教程将详细介绍 GORM 的使用方法。

目录

  1. 安装与配置
  2. 模型定义
  3. 基本CRUD操作
  4. 查询操作
  5. 关联关系
  6. 事务处理
  7. 钩子方法
  8. 高级特性
  9. 性能优化

安装与配置

安装

go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite  # 根据使用的数据库选择对应的驱动

连接数据库

import (
  "gorm.io/gorm"
  "gorm.io/driver/mysql"
)
func main() {
  // MySQL 连接示例
  dsn := "user:pass@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 {
    panic("failed to connect database")
  }

  // SQLite 连接示例
  // db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
}

配置

db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  SkipDefaultTransaction: true,  // 禁用默认事务
  NamingStrategy: schema.NamingStrategy{
    TablePrefix: "t_",   // 表名前缀
    SingularTable: true, // 使用单数表名
  },
  Logger: logger.Default.LogMode(logger.Info), // 日志配置
})

模型定义

基本模型

type User struct {
  gorm.Model        // 内嵌包含ID, CreatedAt, UpdatedAt, DeletedAt字段
  Name      string
  Age       int
  Birthday  time.Time
}

字段标签

type User struct {
  gorm.Model
  Name     string `gorm:"type:varchar(100);uniqueIndex"`
  Age      int    `gorm:"default:18"`
  Birthday time.Time
  Active   bool   `gorm:"default:true"`
  Email    string `gorm:"unique;not null"`
}

表名设置

// 实现TableName方法自定义表名
func (User) TableName() string {
  return "profiles"
}

基本CRUD操作

创建记录

// 创建单条记录
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
result := db.Create(&user)
// 批量插入
users := []User{
  {Name: "Alice", Age: 22},
  {Name: "Bob", Age: 25},
}
db.Create(&users)
// 选择字段创建
db.Select("Name", "Age").Create(&user)
// 忽略字段创建
db.Omit("Age").Create(&user)

查询记录

// 查询单条记录
var user User
db.First(&user, 1)                 // 查询id=1的记录
db.First(&user, "name = ?", "Jinzhu") // 条件查询
// 查询多条记录
var users []User
db.Find(&users, "age > ?", 20)
// 获取第一条记录(按主键排序)
db.First(&user)
// 获取最后一条记录
db.Last(&user)

更新记录

// 更新单个字段
db.Model(&user).Update("name", "hello")
// 更新多个字段
db.Model(&user).Updates(User{Name: "hello", Age: 18})
// 更新选定字段
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18})
// 批量更新
db.Model(User{}).Where("age > ?", 20).Updates(map[string]interface{}{"age": gorm.Expr("age + ?", 1)})

删除记录

// 删除记录
db.Delete(&user)
// 带条件删除
db.Where("name = ?", "Jinzhu").Delete(&user)
// 批量删除
db.Where("age < ?", 20).Delete(&User{})
// 软删除(如果模型有DeletedAt字段)
db.Delete(&user, 1)

查询操作

条件查询

// 字符串条件
db.Where("name = ?", "jinzhu").First(&user)
// 结构体/Map条件
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// 主键查询
db.First(&user, 10) // SELECT * FROM users WHERE id = 10;

高级查询

// Not条件
db.Not("name = ?", "jinzhu").First(&user)
// Or条件
db.Where("name = ?", "jinzhu").Or("name = ?", "alice").Find(&users)
// 排序
db.Order("age desc, name").Find(&users)
// Limit & Offset
db.Limit(10).Offset(5).Find(&users)
// 选择字段
db.Select("name", "age").Find(&users)
// 分组
db.Model(&User{}).Select("name, sum(age) as total").Group("name").Find(&result)

原生SQL

// 原生SQL查询
db.Raw("SELECT id, name, age FROM users WHERE name = ?", "jinzhu").Scan(&result)
// Exec执行原生SQL
db.Exec("DROP TABLE users")

关联关系

一对一

type User struct {
  gorm.Model
  Profile Profile
}
type Profile struct {
  gorm.Model
  UserID uint
  Name   string
}
// 自动创建/迁移表
db.AutoMigrate(&User{}, &Profile{})
// 创建关联
user := User{
  Profile: Profile{Name: "Jinzhu"},
}
db.Create(&user)
// 预加载关联
db.Preload("Profile").First(&user)

一对多

type User struct {
  gorm.Model
  CreditCards []CreditCard
}
type CreditCard struct {
  gorm.Model
  Number string
  UserID uint
}
// 查询
var user User
db.Preload("CreditCards").First(&user, 1)
// 添加关联
db.Model(&user).Association("CreditCards").Append([]CreditCard{
  {Number: "123456"},
  {Number: "789012"},
})

多对多

type User struct {
  gorm.Model
  Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
  gorm.Model
  Name string
}
// 查询
var user User
db.Preload("Languages").First(&user, 1)
// 添加关联
var languages []Language
db.Find(&languages, "name IN ?", []string{"zh", "en"})
db.Model(&user).Association("Languages").Append(languages)

事务处理

自动事务

if err := db.Transaction(func(tx *gorm.DB) error {
  if err := tx.Create(&User{Name: "Gorm"}).Error; err != nil {
    return err
  }

  if err := tx.Create(&User{Name: "Gorm2"}).Error; err != nil {
    return err
  }

  return nil
}); err != nil {
  // 处理错误
}

手动事务

// 开始事务
tx := db.Begin()
if err := tx.Create(&User{Name: "Gorm"}).Error; err != nil {
  tx.Rollback()
  return
}
if err := tx.Create(&User{Name: "Gorm2"}).Error; err != nil {
  tx.Rollback()
  return
}
// 提交事务
tx.Commit()

钩子方法

GORM 提供了模型生命周期钩子:

type User struct {
  gorm.Model
  Name string
}
// 创建前钩子
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
  u.Name = "Mr." + u.Name
  return
}
// 更新前钩子
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
  if u.Age < 0 {
    return errors.New("invalid age")
  }
  return
}
// 查询后钩子
func (u *User) AfterFind(tx *gorm.DB) (err error) {
  fmt.Println("found user:", u.Name)
  return
}

高级特性

复合主键

type Product struct {
  ID           string `gorm:"primaryKey"`
  LanguageCode string `gorm:"primaryKey"`
  Code         string
  Name         string
}

自定义数据类型

import "database/sql/driver"
type JSON json.RawMessage
func (j *JSON) Scan(value interface{}) error {
  // 实现Scan方法
}
func (j JSON) Value() (driver.Value, error) {
  // 实现Value方法
}
type User struct {
  gorm.Model
  Settings JSON
}

连接池配置

sqlDB, err := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量
sqlDB.SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间
sqlDB.SetConnMaxLifetime(time.Hour)

性能优化

  1. 禁用默认事务:对于简单的单次查询,可以禁用默认事务
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
      SkipDefaultTransaction: true,
    })
    
  2. 批量操作:使用批量插入、更新和删除
  3. 预加载:使用Preload避免N+1查询问题
  4. 选择字段:只查询需要的字段
    db.Select("name", "age").Find(&users)
    
  5. 使用缓存:对频繁查询但不常变化的数据使用缓存
  6. 索引优化:为常用查询条件添加索引

总结

GORM 提供了强大而灵活的 ORM 功能,可以大大简化 Go 语言中的数据库操作。通过本教程,你应该已经掌握了 GORM 的核心功能,包括模型定义、CRUD操作、关联关系、事务处理等高级特性。 更多详细内容可以参考 GORM 官方文档









results matching ""

    No results matching ""