作用域允许你复用通用的逻辑,这种共享逻辑需要定义为类型func(*gorm.DB) *gorm.DB
。
查询 Scope 查询示例:
func AmountGreaterThan1000 (db *gorm.DB) *gorm.DB { return db.Where("amount > ?" , 1000 ) } func PaidWithCreditCard (db *gorm.DB) *gorm.DB { return db.Where("pay_mode_sign = ?" , "C" ) } func PaidWithCod (db *gorm.DB) *gorm.DB { return db.Where("pay_mode_sign = ?" , "C" ) } func OrderStatus (status []string ) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { return db.Where("status IN (?)" , status) } } db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders) db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders) db.Scopes(AmountGreaterThan1000, OrderStatus([]string {"paid" , "shipped" })).Find(&orders)
func Paginate (r *http.Request) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { q := r.URL.Query() page, _ := strconv.Atoi(q.Get("page" )) if page <= 0 { page = 1 } pageSize, _ := strconv.Atoi(q.Get("page_size" )) switch { case pageSize > 100 : pageSize = 100 case pageSize <= 0 : pageSize = 10 } offset := (page - 1 ) * pageSize return db.Offset(offset).Limit(pageSize) } } db.Scopes(Paginate(r)).Find(&users) db.Scopes(Paginate(r)).Find(&articles)
动态表 使用 Scopes
来动态指定查询的表
func TableOfYear (user *User, year int ) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { tableName := user.TableName() + strconv.Itoa(year) return db.Table(tableName) } } DB.Scopes(TableOfYear(user, 2019 )).Find(&users) DB.Scopes(TableOfYear(user, 2020 )).Find(&users) func TableOfOrg (user *User, dbName string ) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { tableName := dbName + "." + user.TableName() return db.Table(tableName) } } DB.Scopes(TableOfOrg(user, "org1" )).Find(&users) DB.Scopes(TableOfOrg(user, "org2" )).Find(&users)
更新 Scope 更新、删除示例:
func CurOrganization (r *http.Request) func (db *gorm.DB) *gorm.DB { return func (db *gorm.DB) *gorm.DB { org := r.Query("org" ) if org != "" { var organization Organization if db.Session(&Session{}).First(&organization, "name = ?" , org).Error == nil { return db.Where("org_id = ?" , organization.ID) } } db.AddError("invalid organization" ) return db } } db.Model(&article).Scopes(CurOrganization(r)).Update("Name" , "name 1" ) db.Scopes(CurOrganization(r)).Delete(&Article{})