作用域允许你复用通用的逻辑,这种共享逻辑需要定义为类型func(*gorm.DB) *gorm.DB。
查询
Scope 查询示例:
1. func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
2. return db.Where("amount > ?", 1000)
3. }
5. func PaidWithCreditCard(db *gorm.DB) *gorm.DB {
6. return db.Where("pay_mode_sign = ?", "C")
7. }
9. func PaidWithCod(db *gorm.DB) *gorm.DB {
10. return db.Where("pay_mode_sign = ?", "C")
11. }
13. func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
14. return func (db *gorm.DB) *gorm.DB {
15. return db.Where("status IN (?)", status)
16. }
17. }
19. db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders)
20. // 查找所有金额大于 1000 的信用卡订单
22. db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders)
23. // 查找所有金额大于 1000 的 COD 订单
25. db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
26. // 查找所有金额大于1000 的已付款或已发货订单
分页
1. func Paginate(r *http.Request) func(db *gorm.DB) *gorm.DB {
2. return func (db *gorm.DB) *gorm.DB {
3. q := r.URL.Query()
4. page, _ := strconv.Atoi(q.Get("page"))
5. if page == 0 {
6. page = 1
7. }
9. pageSize, _ := strconv.Atoi(q.Get("page_size"))
10. switch {
11. case pageSize > 100:
12. pageSize = 100
13. case pageSize <= 0:
14. pageSize = 10
15. }
17. offset := (page - 1) * pageSize
18. return db.Offset(offset).Limit(pageSize)
19. }
20. }
22. db.Scopes(Paginate(r)).Find(&users)
23. db.Scopes(Paginate(r)).Find(&articles)
动态表
使用 Scopes 来动态指定查询的表
1. func TableOfYear(user *User, year int) func(db *gorm.DB) *gorm.DB {
2. return func(db *gorm.DB) *gorm.DB {
3. tableName := user.TableName() + strconv.Itoa(year)
4. return db.Table(tableName)
5. }
6. }
8. DB.Scopes(TableOfYear(user, 2019)).Find(&users)
9. // SELECT * FROM users_2019;
11. DB.Scopes(TableOfYear(user, 2020)).Find(&users)
12. // SELECT * FROM users_2020;
14. // Table form different database
15. func TableOfOrg(user *User, dbName string) func(db *gorm.DB) *gorm.DB {
16. return func(db *gorm.DB) *gorm.DB {
17. tableName := dbName + "." + user.TableName()
18. return db.Table(tableName)
19. }
20. }
22. DB.Scopes(TableOfOrg(user, "org1")).Find(&users)
23. // SELECT * FROM org1.users;
25. DB.Scopes(TableOfOrg(user, "org2")).Find(&users)
26. // SELECT * FROM org2.users;
更新
Scope 更新、删除示例:
1. func CurOrganization(r *http.Request) func(db *gorm.DB) *gorm.DB {
2. return func (db *gorm.DB) *gorm.DB {
3. org := r.Query("org")
5. if org != "" {
6. var organization Organization
7. if db.Session(&Session{}).First(&organization, "name = ?", org).Error == nil {
8. return db.Where("org_id = ?", organization.ID)
9. }
10. }
12. db.AddError("invalid organization")
13. return db
14. }
15. }
17. db.Model(&article).Scopes(CurOrganization(r)).Update("Name", "name 1")
18. // UPDATE articles SET name = "name 1" WHERE org_id = 111
19. db.Scopes(CurOrganization(r)).Delete(&Article{})
20. // DELETE FROM articles WHERE org_id = 111
