news 2026/5/11 5:03:57

gorm 1.X db日志 SELECT count(*) FROM “users“ WHERE “users“.“deleted_at“ IS NULL AND ((id = $1)) LIMIT

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gorm 1.X db日志 SELECT count(*) FROM “users“ WHERE “users“.“deleted_at“ IS NULL AND ((id = $1)) LIMIT

这个 GORM 1.x 的 SQL 日志问题。

问题现象

你的 SQL 日志显示:

sql

复制

SELECT count(*) FROM "users" WHERE "users"."deleted_at" IS NULL AND ((id = $1)) LIMIT 1 OFFSET 0 [1929496158825091072] 0

你期望的是:

sql

复制

SELECT count(*) FROM "users" WHERE "users"."deleted_at" IS NULL AND id = 1929496158825091072 LIMIT 1 OFFSET 0

原因分析

这是GORM 1.x 的正常日志行为,不是 Bug:

表格

复制

日志组件行为说明
GORM 内置 Logger出于安全考虑,默认使用占位符$1而非直接拼接参数值
参数列表[1929496158825091072]显示在 SQL 语句之后,表示实际绑定的参数值

解决方案

方案一:启用完整 SQL 打印(调试用途)

go

复制

// 开启详细日志,包含完整 SQL db.LogMode(true) // 或者自定义 Logger,使用 Print SQL 模式 db.SetLogger(gorm.Logger{LogWriter: log.New(os.Stdout, "\r\n", 0)}) db.LogMode(true) // GORM 1.x 中让参数直接拼接到 SQL(不推荐生产环境使用) db.Callback().Query().Register("log", func(scope *gorm.Scope) { // 通过 scope.SQL 和 scope.Vars 手动拼接 log.Println(scope.SQL, scope.Vars) // 这里可以自行格式化输出 })

方案二:自定义 Logger 实现参数内联

go

复制

import ( "log" "os" "fmt" "github.com/jinzhu/gorm" ) // 自定义 Logger type CustomLogger struct{} func (l CustomLogger) Print(v ...interface{}) { if len(v) >= 4 { level := v[0] source := v[1] if level == "sql" { // v[3] 是 SQL 语句,v[4] 是参数数组 sql := v[3].(string) vars := v[4] // 打印带参数的完整 SQL(仅调试用途) fmt.Printf("[SQL] %s | 参数: %v | 来源: %v\n", sql, vars, source) return } } // 其他日志走默认输出 log.New(os.Stdout, "\r\n", 0).Print(v...) } // 使用自定义 Logger db.SetLogger(CustomLogger{}) db.LogMode(true)

方案三:使用第三方 GORM 日志工具

go

复制

import gormlog "github.com/op/go-logging" // 或使用 go-sql-driver/mysql 的 interpolateParams // 但这需要数据库驱动层支持

为什么使用占位符更好?

go

复制

// ❌ 不安全:SELECT ... WHERE id = 192949... // 如果参数包含恶意字符:id = "1 OR 1=1 --",会导致 SQL 注入 // ✅ 安全:使用预处理语句 // 数据库驱动会将参数与 SQL 分离处理

验证实际执行的 SQL

如果你想确认数据库实际收到的 SQL,可以在数据库层面查看:

bash

复制

# PostgreSQL SHOW log_min_duration_statement; SET log_min_duration_statement = 0; -- 记录所有语句 # MySQL SET GLOBAL general_log = 'ON'; SHOW VARIABLES LIKE 'general_log%';

总结$1占位符 + 参数列表的日志格式是 GORM 的设计特性,代表使用了预处理语句(Prepared Statement),这是安全且推荐的做法。如果你确实需要内联参数用于调试,可以使用上述方案二自定义 Logger。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 2:45:58

为什么你的代码能力越强,反而在公司越“不存在“?

你见过这样的开发者吗?代码质量顶级,日更无虚,issue 秒杀,但升职加薪的时候,却始终轮不到他。这不是能力问题,这是能见度问题。被隐形的优秀工程师这是一个有趣的悖论。我见过太多这样的开发者:…

作者头像 李华
网站建设 2026/5/3 6:52:09

Parameter-Efficient Fine-Tuning:LoRA与Q-LoRA的原理与显存优势

全参数微调 DeepSeek-67B 这种巨型模型,无异于在故宫里重修每一块地砖。它不仅需要消耗数百张 NPU 卡的算力,而且生成的每一个权重文件都重达几百 GB。对于大多数企业而言,这种重资产模式既不经济,也不灵活。 PEFT(Par…

作者头像 李华
网站建设 2026/5/3 12:37:54

拖延症福音!AI论文网站 千笔写作工具 VS 灵感风暴AI,专科生专属神器!

随着人工智能技术的迅猛迭代与普及,AI辅助写作工具已逐步渗透到高校学术写作场景中,成为专科生、本科生、研究生完成毕业论文不可或缺的辅助手段。越来越多面临毕业论文压力的学生,开始依赖各类AI工具简化写作流程、提升创作效率。但与此同时…

作者头像 李华
网站建设 2026/5/10 2:53:36

从此告别拖延!口碑爆棚的AI论文工具 —— 千笔·专业论文写作工具

你是否曾为论文选题发愁,面对空白文档无从下手?是否在反复修改中感到力不从心,却始终达不到理想效果?论文写作不仅考验学术能力,更是一场与时间的较量。而如今,一款专为学生打造的AI论文工具——千笔AI&…

作者头像 李华
网站建设 2026/5/10 12:18:01

万国数据宣布私人配售3亿美元 华泰资本认购

雷递网 乐天 2月2日万国数据控股有限公司(简称:“万国数据控股”)日前宣布私人配售3亿美元B轮可转换优先股予一名中国机构投资者华泰资本投资有限公司。万国数据将动用私人配售所得款项扩充数据中心容量及作一般企业用途。可转换优先股包括以…

作者头像 李华