这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记
1. 什么是ORM框架
ORM(Object Relational Mapping,对象关系映射),简单理解就是将面向对象语言的类与关系数据库中的关系的一种映射,并且将对关系型数据库的CRUD操作封装起来,方便开发者使用,其中GORM就是go语言的一个ORM框架。
2. 什么是DSN
DSN(Data Source Name,数据源名称),包含数据库的用户名,密码,连接方式,地址,端口号,数据库名称,字符集等等,一个简单的例子如下:
root:123456@tcp(localhost:3306)/dousheng?charset=utf8mb4&parseTime=True&loc=Local
charset=utf8mb4支持最完整的中英文字符集parseTime=TrueMySQL中的DATE、DATETIME等时间类型字段将自动转换为golang中的time.Time类型loc=Local时区为服务器本地时区
3. GORM连接MySQL
var err error
MyDB, err = gorm.Open(mysql.Open(constants.MySQLDSN),
&gorm.Config{
PrepareStmt: true,
SkipDefaultTransaction: true,
},
)
if err != nil {
panic(err)
}
PrepareStmt所有的操作都会创建并缓存预编译语句,以加速后续执行速度SkipDefaultTransaction跳过系统默认事务DefaultStringSizestring 类型字段的默认长度
4. 连接池
sqlDB, err := MyDB.DB()
if err != nil {
panic(err)
}
sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
SetMaxIdleConns设置空闲连接池中连接的最大数量SetMaxOpenConns设置打开数据库连接的最大数量SetConnMaxLifetime设置了连接可复用的最大时间
5. 模型定义
GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间
GORM 定义一个 gorm.Model 结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
- 嵌入结构体
type User struct {
gorm.Model
Name string
}
// 等效于
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
对于正常的结构体字段,可以通过标签 embedded 将其嵌入
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Author Author `gorm:"embedded"`
Upvotes int32
}
// 等效于
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}
6.简单的CRUD接口
- 创建记录
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
result := db.Create(&user) // 通过数据的指针来创建
user.ID // 返回插入数据的主键
result.Error // 返回 error
result.RowsAffected // 返回插入记录的条数
// 批量插入
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}}
db.Create(&users)
- 查找记录
MyDB.Where("name = ?", name).Find(&res)
MyDB.Where("id in ?", userIDs).Find(&res)
- 删除记录
MyDB.Where("user_id = ? AND video_id = ?", userID, videoID).Delete(&Favorite{})
使用 Unscoped 永久删除匹配的记录
db.Unscoped().Delete(&order)
// DELETE FROM orders WHERE id=10;
- 更新记录
tx := MyDB.WithContext(ctx)
tx.Model(&User{}).Where("ID = ?", followID).Update("follower_count", gorm.Expr("follower_count + ?", 1))
tx.Model(&User{}).Where("ID = ?", followerID).Update("follow_count", gorm.Expr("follow_count + ?", 1))