🌙 1.Scopes
scopes是GORM中的一种链式调用方式,可以用于在查询中添加条件。它的作用是可以将一些常用的查询条件封装成一个scope,方便在多个地方复用。例如, 通用的分页逻辑:
func Paginate(r *http.Request) func(db *gorm.DB) *gorm.DB {
return func (db *gorm.DB) *gorm.DB {
q := r.URL.Query()
page, _ := stronv.Atoi(q.Get("page"))
if pge == 0 {
page = 1
}
switch {
case pageSize > 100:
pageSize = 100
case pageSize <= 0:
pageSize = 10
}
offset := (page - 1) * pageSize
return db.Offset(offset).Limit(pageSize)
}
}
db.Scope(Paginate(r)).Find(&users)
db.Scope(Paginate(r)).Find(&articles)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
🌙 2.智能选择字段
GORM支持在查询时只选择需要的字段,可以使用Select
方法来指定需要选择的字段。例如,我们可以只选择用户的name
和id
字段:
type User struct {
ID uint
Name string
Age int
Gender string
// 假设后面还有很多字段
...
}
type APIUser struct {
ID uint
Name string
}
// 查询时会自动选择 `id`、`name` 字段
db.Model(&User{}).Limit(10).Find(&APIUser{})
// 相当于:SELECT `id`, `name` FROM `users` LIMIT 10
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
🌙 3.子查询
- where 子查询
type User struct {
ID uint
Name string
Age int
Gender string
}
// 查询年龄大于女性平均年龄的用户
// SELECT * FROM `users` WHERE age > (SELECT AVG(age) FROM `users` WHERE gender = 'female')
var users []User
db.Where("age > ?", db.Table("users").Select("AVG(age)").Where("gender = ?", "female").QueryExpr()).Find(&users)
2
3
4
5
6
7
8
9
10
11
- from子查询
// SELECT * FROM (SELECT `name`, `age` FROM `users`) as u WHERE `age` = 18
db.Table("(?) as u", db.Model(&User{}).Select("name", "age")).Where("age = ?", 18).Find(&User{})
subQuery1 := db.Model(&User{}).Select("name")
subQuery2 := db.Model(&Pet{}).Select("name")
db.Table("(?) as u, (?) as p", subQuery1, subQuery2).Find(&User{})
2
3
4
5
6
🌙 4.关联查询
GORM支持多种关联查询,包括一对一、一对多、多对多等。下面将详细介绍这些关联查询的使用方法。
🌙 4.1.一对一关联
一对一关联是指两个表之间的关系是一对一的关系。例如,一个用户只有一个身份证号,一个身份证号也只对应一个用户。在GORM中,我们可以使用hasOne和belongsTo方法来建立一对一关联。
🌙 4.1.1 hasOne
hasOne方法用于建立一个从当前模型到另一个模型的一对一关联。例如,我们可以将User和IDCard模型建立一对一关联:
type User struct {
ID uint
Name string
Age int
Gender string
IDCard IDCard
}
type IDCard struct {
ID uint
Number string
UserID uint
}
// 建立一对一关联
db.Model(&User{}).HasOne(&IDCard{})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
上面的代码中,我们使用HasOne方法将User和IDCard模型建立了一对一关联。这样,在查询User模型时,GORM会自动关联查询IDCard模型,并将查询结果赋值给User模型的IDCard字段。
🌙 4.1.2 belongsTo
belongsTo方法用于建立一个从另一个模型到当前模型的一对一关联。例如,我们可以将IDCard和User模型建立一对一关联:
type User struct {
ID uint
Name string
Age int
Gender string
IDCard IDCard
}
type IDCard struct {
ID uint
Number string
UserID uint
User User
}
// 建立一对一关联
db.Model(&IDCard{}).BelongsTo(&User{})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
🌙 4.2.一对多关联
一对多关联是指一个模型对应多个另一个模型。例如,一个用户可以有多篇文章,一篇文章只能对应一个用户。在GORM中,我们可以使用hasMany和belongsTo方法来建立一对多关联。
🌙 4.2.1 hasMany
hasMany方法用于建立一个从当前模型到另一个模型的一对多关联。例如,我们可以将User和Article模型建立一对多关联:
type User struct {
ID uint
Name string
Age int
Gender string
Articles []Article
}
type Article struct {
ID uint
Title string
Content string
UserID uint
}
// 建立一对多关联
db.Model(&User{}).HasMany(&Article{})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上面的代码中,我们使用HasMany方法将User和Article模型建立了一对多关联。这样,在查询User模型时,GORM会自动关联查询Article模型,并将查询结果赋值给User模型的Articles字段。
🌙 4.2.2 belongsTo
belongsTo方法用于建立一个从另一个模型到当前模型的一对多关联。例如,我们可以将Article和User模型建立一对多关联:
type User struct {
ID uint
Name string
Age int
Gender string
Articles []Article
}
type Article struct {
ID uint
Title string
Content string
UserID uint
User User
}
// 建立一对多关联
db.Model(&Article{}).BelongsTo(&User{})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上面的代码中,我们使用BelongsTo方法将Article和User模型建立了一对多关联。这样,在查询Article模型时,GORM会自动关联查询User模型,并将查询结果赋值给Article模型的User字段。
🌙 4.3.多对多关联
多对多关联是指两个模型之间的关系是多对多的关系。例如,一个用户可以有多个角色,一个角色也可以对应多个用户。在GORM中,我们可以使用many2many方法来建立多对多关联。
type User struct {
ID uint
Name string
Age int
Gender string
Roles []Role `gorm:"many2many:user_roles;"`
}
type Role struct {
ID uint
Name string
Users []User `gorm:"many2many:user_roles;"`
}
// 建立多对多关联
db.Model(&User{}).Association("Roles").Append(&Role{Name: "admin"})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
上面的代码中,我们使用many2many方法将User和Role模型建立了多对多关联。这样,在查询User模型时,GORM会自动关联查询Role模型,并将查询结果赋值给User模型的Roles字段。
在添加关联时,我们可以使用Association方法来添加关联。例如,我们可以将一个用户和一个角色关联起来:
db.Model(&User{}).Association("Roles").Append(&Role{Name: "admin"})
2
上面的代码中,我们使用Association方法将一个用户和一个角色关联起来。这样,在查询User模型时,GORM会自动关联查询Role模型,并将查询结果赋值给User模型的Roles字段。