G

[Golang] GORM框架 Scope

RoLingG 2024-10-10

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操作语句。

上面的ActivatedScopeOrderedByCreationDateScope就是两个 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 的好处包括:

提高抽象程度

  1. 封装复杂逻辑:通过将复杂的查询逻辑封装在 Scopes 中,您可以隐藏实现细节,只暴露简单的接口。
  2. 减少重复代码Scopes 允许您定义可重用的查询片段,这样可以避免在多个地方重复相同的代码。
  3. 提高代码可读性:使用 Scopes 可以将复杂的查询条件分解成更小、更易于理解的部分。

提高代码质量

  1. 易于维护:当查询逻辑需要更新时,您只需修改 Scopes 函数,而不必在多个地方进行更改。
  2. 增强一致性:使用 Scopes 可以确保整个项目中查询逻辑的一致性。
  3. 便于测试Scopes 可以单独测试,这使得测试变得更加容易和可靠。
  4. 动态组合:可以在不同的查询中动态地组合不同的 Scopes,提高了代码的灵活性。

促进代码组织

  1. 模块化设计Scopes 支持模块化设计,使得代码更加组织化和结构化。
  2. 关注点分离Scopes 帮助将业务逻辑(如权限检查、过滤条件)与数据访问逻辑分离。
PREV
[Golang] GORM框架 三种特殊查询
NEXT
[Golang] GORM框架 Session

评论(0)

发布评论