结构体字段必须首字母大写才能被sqlx/gorm反射读取,小写字段会被静默忽略;db和gorm标签需分别匹配对应库的列名,混用时须保持一致;默认蛇形命名在大小写敏感数据库中易失效,应显式指定column;json标签不影响数据库操作,不可替代db/gorm标签。

结构体字段没导出,sqlx/gorm 读不到数据
字段首字母小写(比如 id string)会导致 sqlx、gorm 等库完全跳过该字段——不是报错,而是静默忽略,查询结果里对应字段永远是零值。
- 必须用大写字母开头(
ID int、Name string),才能被反射访问 - 标签里的数据库列名可以任意(
db:"user_id"或gorm:"column:user_id"),但字段本身得导出 - 常见误写:
userID string→ 字段名合法,但若没加db或gorm标签,仍按默认规则映射;加了标签却首字母小写,标签直接失效
db 标签和 gorm 标签混用时字段名冲突
同一个字段同时写 db:"user_id" 和 gorm:"column:uid",sqlx 读取时用前者,gorm 操作时用后者——看起来没问题,但容易在联查或手动 SQL 中漏掉一致性检查。
- sqlx 的
Select依赖db标签,不认gorm;gorm 的AutoMigrate和Save只看gorm标签 - 如果数据库列名是
uid,但db标签写成db:"user_id",sqlx 查询会报sql: expected 1 destination argument, got 2或字段为零值 - 建议:同一项目统一用一套 ORM(要么全 sqlx +
db,要么全 gorm +gorm),避免混用;非要混用,确保两个标签值一致
gorm 默认蛇形命名 vs 实际表字段大小写敏感
gorm 默认把 UserName 映射成 user_name,但某些数据库(如 PostgreSQL)对列名大小写敏感,而你表里实际列名是 UserName 或 USERNAME,这时默认规则就失灵。
- 别依赖默认映射,尤其对接旧库时,显式写
gorm:"column:UserName" - PostgreSQL 中双引号包裹的列名(
"UserName")是大小写敏感的,gorm 不会自动加引号,所以标签值必须严格匹配 - MySQL 默认不区分大小写,但开启
lower_case_table_names=0后列名也敏感,同样要核对标签值
json 标签干扰数据库操作的典型陷阱
很多人把 json:"user_id" 和 db:"user_id" 写在同一字段,觉得“反正都是映射”,但 json 标签对数据库操作毫无影响,反而可能掩盖真实问题。
-
json标签只在序列化/反序列化时起作用;db或gorm标签才控制数据库行为 - 错误示范:
ID int `json:"id" db:"id"`→ 看起来整洁,但如果数据库列名其实是user_id,这里db:"id"就错了,而json:"id"完全无关,容易让人误以为“标签都写了,应该没问题” - 真正要盯的是:SQL 查询返回的列名、结构体字段名、对应标签值三者是否一致;json 标签只是 API 层的事,不该掺和到数据库映射逻辑里
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











