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

Go语言使用GORM实现动态过滤查询 避免冗余代码的方法

GORM 实现动态可选过滤查询的方案

需求背景

我正在开发一个接收过滤参数的API,参数格式如下:

/api/endpoint?filter_key_1=filter_value_1&...

此前在Spring框架开发时,可通过Criteria API轻松实现SQL查询的动态构建。目前我在Go语言中使用GORM处理ORM操作,想要实现支持可选参数的动态查询,无需编写冗余代码。

具体需求示例

  • 当收到请求为:
    /api/endpoint?fk_1=fv_1&fk_2=fv_2&fk_3=fv_3
    
    期望生成的SQL为:
    select * from table where fk_1 = fv_1 AND fk_2 = fv_2 AND fk_3 = fv_3
    
  • 当收到请求为:
    /api/endpoint?fk_1=fv_1
    
    期望生成的SQL为:
    select * from table where fk_1 = fv_1
    

现有实现的缺陷

我当前的实现方案是逐个判断参数是否存在,再拼接SQL字符串:

query:="select * from table where "
if fk_1 != ""{
    query += "fk_1 = fv_1"
}
// ...其余参数逐个判断拼接

这种实现非常不规范,容易出错,还存在SQL注入的安全风险。

可行解决方案

GORM原生支持传入map[string]interface{}类型作为Where条件,会自动将map的键作为查询字段、值作为匹配值,多个键值对自动用AND连接,空值不会加入查询条件,无需手动拼接SQL。

我们只需要把接口收到的map[string][]string格式的请求参数,转换为GORM支持的格式即可,示例代码如下:

// 定义允许外部查询的字段白名单,避免敏感字段被恶意查询
var allowedQueryFields = map[string]bool{
    "fk_1": true,
    "fk_2": true,
    "fk_3": true,
}

// 处理请求参数,生成GORM查询map
queryMap := make(map[string]interface{})
for k, vals := range r.URL.Query() {
    // 校验字段是否在白名单内、参数值非空
    if allowedQueryFields[k] && len(vals) > 0 && vals[0] != "" {
        queryMap[k] = vals[0]
    }
}

// 直接执行查询
var results []YourModel
err := db.Model(&YourModel{}).Where(queryMap).Find(&results).Error

注意:必须加字段白名单校验,避免用户传入未开放的敏感字段(比如password、is_admin等)进行非法查询,引发安全问题。

该方案无需编写冗余的参数判断逻辑,也避免了手动拼接SQL的安全风险,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:39:03