文章目录
- [ORM 是什么?](#ORM 是什么?)
- [GORM 简介](#GORM 简介)
- 初始化数据库连接
- [定义 Model(结构体)](#定义 Model(结构体))
- 自动迁移(创建表)
- [CRUD 基本操作](#CRUD 基本操作)
- 关联关系(常用)
- Hooks(回调)
- 高级功能
- [Go + GORM 的工程化思路](#Go + GORM 的工程化思路)
在 HOW - Go 开发入门(一) 我们进行了开发入门的开篇介绍。今天我们主要介绍第 3 步:接数据库(ORM)。
ORM 是什么?
ORM = Object-Relational Mapping(对象关系映射)
- 核心目标:把数据库表和 Go 的 struct 对象 一一对应
- 不用写大量 SQL,直接用熟悉的 struct + 方法操作数据库
- 优势:
- 简化开发
- 避免手写重复 SQL
- 提高可维护性
GORM 简介
GORM 是 Go 生态最流行的 ORM:
- 支持 MySQL、Postgres、SQLite、SQLServer 等
- 提供:
- 自动迁移(自动生成表结构)
- CRUD 方法
- 关联关系(One2Many, Many2Many)
- Hooks(回调:BeforeCreate, AfterUpdate 等)
- 易用又贴近 Go 风格
初始化数据库连接
go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
_ = db
}
说明:
dsn:数据库连接字符串gorm.Open:返回*gorm.DB对象,用于操作数据库
定义 Model(结构体)
go
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:100"`
Age int
}
ID主键Name限制长度 100Age默认 int- GORM 会自动根据 struct 创建对应表
自动迁移(创建表)
go
db.AutoMigrate(&User{})
- 自动创建表或修改表结构
- 推荐在项目启动时调用
CRUD 基本操作
Create
go
db.Create(&User{Name: "Tom", Age: 18})
- 插入一条数据
- 自动填充 ID
Read
go
var user User
db.First(&user, 1) // 根据主键查
db.Where("name = ?", "Tom").Find(&user) // 条件查询
Update
go
db.Model(&user).Update("Age", 20)
db.Model(&user).Updates(User{Name: "Tommy", Age: 21})
Delete
go
db.Delete(&user) // 根据主键删除
关联关系(常用)
One2Many
go
type Order struct {
ID uint
UserID uint
Total float64
}
type User struct {
ID uint
Name string
Orders []Order
}
- GORM 会自动识别
UserID外键 - 查用户 + 订单:
go
var user User
db.Preload("Orders").First(&user, 1)
Many2Many
go
type Role struct {
ID uint
Name string
Users []User `gorm:"many2many:user_roles;"`
}
- 自动生成中间表
user_roles
Hooks(回调)
- BeforeCreate / AfterCreate / BeforeUpdate / AfterDelete
- 用于做统一日志、验证、缓存等
go
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
if u.Age < 0 {
return errors.New("invalid age")
}
return nil
}
高级功能
- 事务
go
tx := db.Begin()
if err := tx.Create(&User{Name: "Alice"}).Error; err != nil {
tx.Rollback()
} else {
tx.Commit()
}
- 原生 SQL
go
db.Raw("SELECT * FROM users WHERE age > ?", 18).Scan(&users)
Go + GORM 的工程化思路
- 每张表定义一个 struct(model)
- 提供 CRUD 方法(Repository/Service 层)
- 启动时自动迁移表
- 对于复杂查询,使用原生 SQL 或 chain 方法
- 用 interface 封装数据库操作 → 可替换 MySQL / Postgres / 测试 mock