如何在Golang中使用$参数构建PostgreSQL过滤查询
Go中PostgreSQL动态参数化查询实现方案
直接上修改后的完整代码,既实现参数化过滤,又支持分页功能:
import "fmt" // 初始化基础SQL语句 q := `select m.*, ms.fullname as singer, l.name as lang, c.name as country from music m LEFT JOIN music_singer ms ON ms.uuid = m.singer_id LEFT JOIN language l ON l.uuid = m.language_id LEFT JOIN countries c ON c.uuid = m.country_id where m.status = true ` // 用切片存储所有动态参数,避免字符串拼接注入风险 params := []interface{}{} // 动态添加LanguageID过滤条件(参数化形式) if dto.LanguageID != "" { params = append(params, dto.LanguageID) q += fmt.Sprintf(` and m.language_id = $%d `, len(params)) } // 动态添加CountryID过滤条件(参数化形式) if dto.CountryID != "" { params = append(params, dto.CountryID) q += fmt.Sprintf(` and m.country_id = $%d `, len(params)) } // 处理分页参数(可根据业务调整limit和page的默认值) limit := 20 page := 0 offset := page * limit // 追加limit参数 params = append(params, limit) q += fmt.Sprintf(` limit $%d `, len(params)) // 追加offset参数 params = append(params, offset) q += fmt.Sprintf(` offset $%d `, len(params)) // 执行参数化查询 rows, err := r.client.Query(ctx, q, params...) defer rows.Close() // 后续结果处理逻辑...
关键注意点
- 杜绝SQL注入:所有用户输入(过滤条件、分页参数)均通过
params切片传递,全程使用$N占位符,完全避免字符串拼接带来的注入风险。 - 占位符编号规则:每次追加参数后,用
len(params)作为当前参数对应的占位符编号,确保编号与参数顺序严格对应。 - 分页逻辑调整:如果你的分页规则是
page从1开始,将offset计算改为(page-1)*limit即可。 - 扩展性:后续新增过滤条件(如歌手ID、发布时间范围)时,直接复用这套逻辑:先追加参数到切片,再拼接带对应占位符的SQL片段。
内容的提问来源于stack exchange,提问作者Gadam Gurban
相关产品推荐
相关产品推荐

