You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go Gorm框架分组条件失效:自定义搜索查询的OR分组需求

问题:自定义搜索查询无法生成带分组的OR条件SQL

我正在实现自定义搜索查询逻辑,规则是请求字段名对应数据库查询字段的AliasName,当AliasName包含|分隔符时,需要通过Where+Or实现多字段的或查询。

当前实现代码

db := core.NewDBAutoConfig(config.GetDevMysql())
easySearch := core.NewEasySearch(db, map[string]interface{}{
        "name": "1111",
        "age":  18,
    })
easySearch.AddRule(&core.SearchRule{Name: "name", AliasName: "a.name|a.sex", SearchType: core.Like})
easySearch.AddRule(&core.SearchRule{Name: "age", AliasName: "a.age", SearchType: core.Equals})

db = easySearch.Build()

匹配逻辑代码

if strings.Index(config.ColumnName, ColumnSeparator) > 0 {
    columnNames := strings.Split(config.ColumnName, ColumnSeparator)
    for i := 0; i < len(columnNames); i++ {
        args = append(args, columnNames[i])
        args = append(args, matchValue...)
        if i <= 0 {
            s.db = s.db.Where(matchQuery, args...)
        } else {
            s.db = s.db.Or(matchQuery, args...)
        }
    }
    s.db = s.db.Where(s.db)
} else {
    args = append(args, config.ColumnName)
    args = append(args, matchValue...)
    s.db = s.db.Where(matchQuery, args...)
}

当前问题与期望结果

当前生成的SQL没有正确的分组结构,导致OR条件和后续AND条件的逻辑优先级错误,期望生成的SQL是:

SELECT * FROM `yhyh_user` WHERE (`a.name` LIKE '%1111%' OR `a.sex` LIKE '%1111%') AND `a.age` = 18

解决方案

问题核心是没有将OR条件包裹在分组括号里,大多数Go ORM(比如GORM)支持通过闭包参数实现分组条件,自动生成括号包裹的逻辑。修改后的匹配逻辑如下:

if strings.Index(config.ColumnName, ColumnSeparator) > 0 {
    columnNames := strings.Split(config.ColumnName, ColumnSeparator)
    // 用闭包创建分组OR条件,ORM会自动添加括号
    s.db = s.db.Where(func(tx *gorm.DB) *gorm.DB {
        for i, col := range columnNames {
            // 每个字段单独构建参数,避免参数顺序混乱
            currentArgs := append([]interface{}{col}, matchValue...)
            if i == 0 {
                tx = tx.Where(matchQuery, currentArgs...)
            } else {
                tx = tx.Or(matchQuery, currentArgs...)
            }
        }
        return tx
    })
} else {
    args = append(args, config.ColumnName)
    args = append(args, matchValue...)
    s.db = s.db.Where(matchQuery, args...)
}

修改说明

  1. 闭包分组:将OR条件的循环逻辑放在闭包中传递给Where,ORM会自动将闭包内的所有条件用括号包裹,形成独立的逻辑分组
  2. 参数独立:循环中为每个字段单独构建参数列表,避免原代码中累加args导致的参数顺序错误
  3. 移除冗余代码:删掉原代码中s.db = s.db.Where(s.db)这行,它会导致不必要的嵌套,破坏SQL结构

修改后生成的SQL会自动带上括号,确保OR条件的逻辑优先级正确,和后续的AND条件组合成符合预期的查询语句。

内容的提问来源于stack exchange,提问作者yyds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:23:36