news 2026/7/8 1:51:20

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/7/1 9:40:19

SpaceX星际先行者的三重跃迁:从基本盘到太空生态的万亿蓝图

摘要:本报告聚焦SpaceX商业航天生态,内容覆盖星链、火箭发射、太空算力、太空光伏及月球经济、火星殖民五大核心板块,同步梳理SpaceX供应链、国内火箭/卫星/太空算力赛道投资标的,分析存在的物理瓶颈、成本、运维等风险&#xff0…

作者头像 李华
网站建设 2026/7/1 3:18:43

学长亲荐 10个AI论文写作软件:专科生毕业论文+开题报告高效工具测评

在当前学术写作环境日益复杂的背景下,专科生在撰写毕业论文和开题报告时常常面临内容构思困难、资料查找繁琐、格式规范不熟悉等多重挑战。为了帮助更多学生高效完成学术任务,笔者基于2026年的实测数据与真实用户反馈,对市面上主流的AI论文写…

作者头像 李华
网站建设 2026/7/1 9:40:18

一天一个Python库:fsspec - 统一文件系统接口,轻松访问数据

fsspec - 统一文件系统接口,轻松访问数据 一、什么是fsspec? fsspec 是一个用于提供统一文件系统接口的 Python 库。它抽象了各种文件系统(如本地文件系统、S3、GCS、HDFS等)的细节,让你可以用统一的方式操作文件。 它…

作者头像 李华
网站建设 2026/6/30 14:10:33

芯片专家的“黑箱决策”正在拖垮团队

芯片团队开会的经典场景:讨论了两小时的时序方案,争得面红耳赤。这时资深专家敲敲桌子:“就用方案B。”会议室安静了。没人问为什么,也没人敢问。这就是芯片行业最普遍的决策方式——专家拍板,过程保密。不是说专家的判断一定错。恰恰相反,很多时候他们是…

作者头像 李华
网站建设 2026/7/1 9:40:24

计算机毕业设计springboot图书在线借阅系统 基于SpringBoot的智慧图书馆借阅服务平台 高校数字化图书借还管理系统的设计与实现

计算机毕业设计springboot图书在线借阅系统v6fh70kc (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着信息技术的飞速发展和移动互联网的普及,传统图书馆管理模式…

作者头像 李华
网站建设 2026/7/1 9:40:32

计算机毕业设计springboot高校毕业生就业岗位推荐系统 基于SpringBoot的高校毕业生求职智能匹配服务平台 高校毕业生就业职位精准推荐与管理系统

计算机毕业设计springboot高校毕业生就业岗位推荐系统dym6tr30 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着高等教育规模持续扩大,每年数百万毕业生涌入就业市…

作者头像 李华