sqlx.queryrow()仅封装查询与扫描,不处理结构体字段映射;sqlx.get()在此基础上自动绑定struct字段(依db tag或列名),适合struct单行查询,但字段不匹配时静默置零,而queryrow().scan()报错更明确。

sqlx.QueryRow() 和 sqlx.Get() 有什么区别?
sqlx.QueryRow() 是标准库 database/sql 的直接封装,只做查询 + 扫描,不处理结构体字段映射逻辑;sqlx.Get() 则在内部调用 QueryRow() 后,额外执行结构体字段自动绑定(基于 tag 或列名),更适合 struct scan 场景。
- 如果你查单行且目标是 struct,优先用
sqlx.Get(),少写一行Scan() -
sqlx.QueryRow().Scan()更适合查基础类型(如int、string)或临时匿名结构,避免定义 struct - 注意:如果 struct 字段没加
dbtag 且列名不匹配(比如数据库是user_name,struct 字段是UserName),Get()会静默失败(字段保持零值),而QueryRow().Scan()会报sql.ErrNoRows或类型不匹配错误,更容易定位问题
为什么 Scan() 总报 “expected 3 destination arguments, got 2”?
这是字段数和接收变量数量不一致的典型错误,常见于 SELECT 列表与 struct 字段 / 变量列表不严格对应。
- 检查 SQL 中是否用了
*,但 struct 少了某个字段(比如新增了updated_at,但 struct 没加) - 使用
sqlx.Select()查多行时,必须确保目标 slice 元素类型能完整接收所有列;否则改用sqlx.Query()+ 手动Scan() - 别依赖数据库列顺序——显式写出 SELECT 字段,并按顺序提供变量或 struct 字段(
dbtag 要和字段名一致,不是列名) - 示例:
var u User err := db.Get(&u, "SELECT id, name FROM users WHERE id = ?", 123)
如果User有三个字段,但 SELECT 只写了两个,就会触发这个错误
db.Queryx() 报错 “sql: expected 0 arguments, got 1”,怎么修?
说明你传了参数,但 SQL 字符串里没写占位符,或者用了错误的占位符语法。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
sqlx默认使用?占位符(兼容database/sql),不是$1、:name或%s - PostgreSQL 用户容易踩坑:即使驱动是
lib/pq,sqlx默认仍走?;如需$1,得初始化时传sqlx.DB{DriverName: "postgres", ...}并确保底层 driver 支持 - 检查 SQL 字符串是否被意外拼接(比如
"WHERE id = " + strconv.Itoa(id)),这会导致参数失效,还可能引发 SQL 注入 - 正确写法:
rows, err := db.Queryx("SELECT * FROM users WHERE status = ?", "active")
嵌套 struct 或 map 扫描不出来,是 bug 吗?
不是 bug,是 sqlx 的设计限制:它只支持一级 struct 字段扫描,不递归解析嵌套结构或 map。
- 嵌套 struct 字段(如
User.Profile.Name)不会被自动填充,字段保持零值 -
map[string]interface{}不能直接作为Get()或Select()的目标,会 panic - 解决方案只有两个:
- 把嵌套字段拍平到顶层 struct(比如
ProfileName string <code>db:"profile_name") - 改用
db.Query()+rows.MapScan()得到map[string]interface{},再手动构造嵌套结构
- 把嵌套字段拍平到顶层 struct(比如
- 注意:字段 tag 中的
db名必须和查询出的列名完全一致(大小写敏感),别指望它自动下划线转驼峰——除非你启用了sqlx.NameMapper,但这属于高级配置,多数项目没必要碰
实际用下来,最常卡住人的不是语法,而是字段名和列名之间那层薄薄的映射关系——写错一个下划线,整条 Scan 就静默失效。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










