什么是Gorm Scopes?
Gorm Scope是gorm库中的一个非常重要的特性,它可以让你复用你的逻辑。在gorm中,Scope被定义为一个具有一定作用域的函数,它可以在查询时自动应用于所有模型中。
如何使用gorm Scope?
在gorm中,你可以通过定义一个Scope函数来使用它。Scope函数需要接收一个gorm.DB类型的参数,并且通常会返回一个gorm.DB类型的值。在Scope函数中,你可以对传入的gorm.DB类型进行任意的操作,比如添加限制条件或者修改查询语句等等。
一个简单的例子
func MyScope() func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("deleted_at is null")
}
}
db.Scopes(MyScope()).Find(&users)
在这个例子中,我们定义了一个名为MyScope的Scope函数,并在查询时应用了它。在MyScope函数中,我们使用了db.Where方法,将限制条件添加到了查询中。这样一来,在查询时,所有的结果都会被限制为deleted_at为空的记录。
Scope的链式调用
在gorm中,Scope函数可以被链式调用。这意味着你可以将多个Scope函数组合在一起使用,以实现更为复杂的查询逻辑。
func MyScope1() func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("deleted_at is null")
}
}
func MyScope2() func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("age > 18")
}
}
db.Scopes(MyScope1(), MyScope2()).Find(&users)
在这个例子中,我们定义了两个Scope函数MyScope1和MyScope2,并在查询时应用了它们。在这个查询中,只有deleted_at为空且年龄大于18的记录才会被返回。
Scope的参数化
在某些情况下,你可能需要将参数传递给Scope函数,以便在查询时使用它们。在gorm中,你可以通过在Scope函数中定义参数来实现这个目的。
func MyScope3(age int) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("age > ?", age)
}
}
db.Scopes(MyScope3(18)).Find(&users)
在这个例子中,我们定义了一个名为MyScope3的Scope函数,并在查询时传递了一个age参数。在MyScope3函数中,我们使用了db.Where方法,并使用了?占位符来表示参数。在查询时,18岁以上的用户将会被返回。
使用场景——分页功能
我们在这儿举一个常见的例子,比如复用分页逻辑,具体代码如下:
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)
总结
gorm Scope是一个非常强大的特性,它可以让你复用你的逻辑,在查询时实现更为复杂的查询逻辑。在使用gorm Scope时,你需要定义一个Scope函数,并在查询时应用它。Scope函数可以被链式调用,并且可以接收参数。学习并掌握这个特性将会使你在编写gorm查询时事半功倍。
评论(0)