Scopes
举个例子:
// ActivatedScope 返回启用状态的用户
func ActivatedScope(db *gorm.DB) *gorm.DB {
return db.Where("active = ?", true)
}
// OrderedByCreationDateScope 返回按创建时间排序的用户
func OrderedByCreationDateScope(db *gorm.DB) *gorm.DB {
return db.Order("created_at DESC")
}
func main() {
db, err := gorm.Open(...) // 连接数据库
if err != nil {
panic("failed to connect database")
}
// 使用 Scopes 获取启用状态的用户列表,并按创建时间排序
var users []models.User
db.Scopes(models.ActivatedScope, models.OrderedByCreationDateScope).Find(&users)
if err != nil {
panic(err)
}
fmt.Println(users)
}
Scopes
的用法就是将我们平时写的一长串的 Where(...)
、Order(...)
等Gorm关键词的短句给集成在一个函数或这个函数里,然后通过Scopes调用拼接成一个完整Gorm的Sql操作语句。
上面的ActivatedScope
和OrderedByCreationDateScope
就是两个 Scopes
。
这种方法可以有效提高代码的抽象程度和整体代码质量,例如:
// 筛选出特定类型的记录
func TypeScope(typename string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("type = ?", typename)
}
}
// 根据关键字过滤记录
func KeywordQuery(keyword string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("name LIKE ?", "%"+keyword+"%")
}
}
// 执行特定的联接操作
func InnerJoinDeployKeys(projectID int64, enabled bool, includeArchived bool) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Joins("INNER JOIN deploy_keys ON deploy_keys.project_id = projects.id").
Where("deploy_keys.enabled = ?", enabled).
Where("projects.id = ?", projectID).
Where("deploy_keys.archived = ?", includeArchived)
}
}
想要执行上面的代码:
var keys []SshKey
result := DB.Scopes(TypeScope("MyType"), KeywordQuery("example"), InnerJoinDeployKeys(1, true, false)).
Order("created_at DESC").
Limit(10).
Offset(20).
Find(&keys)
if result.Error != nil {
// 处理错误
}
总结
使用 Scopes
的好处包括:
提高抽象程度
- 封装复杂逻辑:通过将复杂的查询逻辑封装在
Scopes
中,您可以隐藏实现细节,只暴露简单的接口。 - 减少重复代码:
Scopes
允许您定义可重用的查询片段,这样可以避免在多个地方重复相同的代码。 - 提高代码可读性:使用
Scopes
可以将复杂的查询条件分解成更小、更易于理解的部分。
提高代码质量
- 易于维护:当查询逻辑需要更新时,您只需修改
Scopes
函数,而不必在多个地方进行更改。 - 增强一致性:使用
Scopes
可以确保整个项目中查询逻辑的一致性。 - 便于测试:
Scopes
可以单独测试,这使得测试变得更加容易和可靠。 - 动态组合:可以在不同的查询中动态地组合不同的
Scopes
,提高了代码的灵活性。
促进代码组织
- 模块化设计:
Scopes
支持模块化设计,使得代码更加组织化和结构化。 - 关注点分离:
Scopes
帮助将业务逻辑(如权限检查、过滤条件)与数据访问逻辑分离。
评论(0)