一、什么是结构体标签(Struct Tag)
Go 里面:
结构体字段后面经常会跟一串奇怪的东西:
go
Nickname string `json:"nickname" gorm:"column:nickname" toml:"nickname"`
这个东西:
叫:
txt
结构体标签(Struct Tag)
它本质上:
txt
是给框架看的"额外说明"
告诉:
- Gin
- Gorm
- JSON
- ini
- toml
这些框架:
txt
这个字段该怎么映射
二、结构体标签的本质
你一定要理解:
txt
Go 结构体字段名
和
外部数据名字
经常不一样
例如:
Go 字段
go
Title
JSON
json
"title"
数据库
sql
title
配置文件
toml
title = "xxx"
所以:
需要:
txt
标签来建立映射关系
三、结构体标签本质是"翻译官"
例如:
go
Title string `json:"title"`
意思:
txt
JSON里的 title
对应
Go里的 Title
四、三种最常见标签
| 标签 | 场景 | 数据流向 |
|---|---|---|
| json | 前后端交互 | JSON ↔ Go |
| gorm | 数据库映射 | Go ↔ MySQL |
| toml / ini | 配置文件 | 配置文件 → Go |
五、json 标签(前后端交互)
这是:
Gin 里面最最最常见的标签。
示例
go
type User struct {
Username string `json:"username"`
}
六、前端发送 JSON
前端:
json
{
"username":"zhangsan"
}
七、Gin 接收数据
go
var body User
c.ShouldBindJSON(&body)
八、这里到底发生了什么(核心)
Gin:
会:
第一步:读取 Body
读取:
json
{
"username":"zhangsan"
}
第二步:解析 JSON
变成:
txt
key-value
第三步:根据标签匹配
看到:
go
Username string `json:"username"`
于是:
txt
JSON 的 username
↓
对应
Go 的 Username
第四步:赋值
最终:
go
body.Username = "zhangsan"
九、json 标签为什么是双向的
很多新人:
以为:
txt
json 标签只能接收数据
其实:
txt
返回 JSON 时也会用
示例
go
c.JSON(200, body)
Gin:
会:
go
body.Username
根据:
go
json:"username"
转换成:
json
{
"username":"zhangsan"
}
十、所以 json 标签本质
txt
输入:
JSON → Go
输出:
Go → JSON
所以:
txt
是双向映射
十一、完整 JSON 数据流(重点)
txt
前端 JSON
{
"title":"学Gin"
}
↓ c.ShouldBindJSON
Go结构体
body.Title = "学Gin"
↓ c.JSON
返回 JSON
{
"title":"学Gin"
}
十二、gorm 标签(数据库映射)
gorm 标签:
负责:
txt
Go结构体 ↔ 数据库表
十三、示例
go
type Todo struct {
ID uint `gorm:"primaryKey"`
Title string `gorm:"column:title"`
}
十四、gorm:"column:title"
表示:
txt
数据库列 title
对应
Go字段 Title
十五、GORM Create 到底发生了什么
go
db.Create(&todo)
GORM:
会:
第一步
读取结构体:
go
todo.Title
第二步
看到:
go
gorm:"column:title"
第三步
生成 SQL:
sql
INSERT INTO todos (title)
VALUES ('学Gin')
十六、GORM 查询过程
go
db.First(&todo, 1)
数据库:
返回:
sql
title = "学Gin"
GORM:
再根据:
go
gorm:"column:title"
赋值:
go
todo.Title = "学Gin"
十七、所以 gorm 也是双向的
txt
Go → SQL
SQL → Go
十八、GORM 自动规则
如果你不写标签:
GORM 默认:
结构体名
go
Todo
自动变:
sql
todos
字段名
go
Title
自动变:
sql
title
十九、primaryKey 是什么
go
ID uint `gorm:"primaryKey"`
表示:
txt
主键
二十、主键的三个特性
1. 唯一
不能重复。
2. 不能为空
每行必须有。
3. 一张表只能一个主键
二十一、GORM 里的主键默认自增
例如:
go
ID uint `gorm:"primaryKey"`
插入时:
txt
不用手动赋值
MySQL:
自动:
txt
1
2
3
4
增长。
二十二、索引(非常重要)
很多新人:
以为:
txt
WHERE 才是查找
其实:
txt
索引决定查找快不快
二十三、普通索引
go
gorm:"index"
作用:
txt
查询更快
允许重复
二十四、唯一索引
go
gorm:"uniqueIndex"
作用:
txt
查询更快
不能重复
例如:
txt
用户名
手机号
邮箱
二十五、为什么索引会快
你可以理解成:
txt
给数据贴目录标签
没有索引:
txt
全表扫描
有索引:
txt
直接定位
二十六、软删除(重点)
很多公司:
删除数据:
并不会:
sql
DELETE
而是:
txt
标记已删除
示例
go
DeletedAt gorm.DeletedAt
二十七、软删除底层
GORM:
执行:
go
db.Delete(&user)
其实:
不是:
sql
DELETE
而是:
sql
UPDATE users
SET deleted_at = NOW()
二十八、为什么不用真删除
因为:
真实项目:
txt
数据可能需要恢复
例如:
- 订单
- 用户
- 日志
二十九、配置文件标签(ini/toml)
例如:
go
type MysqlConfig struct {
Host string `toml:"host"`
}
三十、配置文件
toml
host = "127.0.0.1"
三十一、读取过程
go
toml.DecodeFile("config.toml", &conf)
框架:
会:
txt
读取 toml
↓
找到 host
↓
赋值给 Host
三十二、ini.MapTo 本质一样
go
ini.MapTo(&conf, "config.ini")
也是:
txt
配置文件
↓
结构体
三十三、配置文件为什么是单向
因为:
一般:
txt
只读配置
不写回配置文件
所以:
txt
配置文件 → Go
通常:
是单向。
三十四、完整数据流向(最重要)
真正项目里:
数据会这样流动:
前端 → 后端
txt
JSON
↓
ShouldBindJSON
↓
Go结构体
后端 → 数据库
txt
Go结构体
↓
GORM
↓
MySQL
配置文件 → 项目
txt
config.toml
↓
DecodeFile
↓
结构体
三十五、结构体为什么这么重要
你会发现:
txt
前端
数据库
配置文件
最后:
都在围绕:
txt
Go结构体
转。
所以:
txt
结构体
是整个Go后端的数据中心
三十六、最终核心图(必须理解)
txt
前端 JSON
↓
json 标签
↓
Go结构体
↓
gorm 标签
↓
MySQL数据库
以及:
txt
config.toml
↓
toml标签
↓
Go结构体
三十七、最后总结
结构体标签本质:
txt
不同数据格式之间的映射规则
最常见三种:
| 标签 | 作用 |
|---|---|
| json | 前后端 JSON 映射 |
| gorm | 数据库字段映射 |
| toml/ini | 配置文件映射 |
真正核心思想:
txt
结构体是中间桥梁
标签负责建立映射
整个 Go Web 开发:
几乎都围绕:
txt
结构体 + 标签
展开。