「go-zero 生成 Model 的命令到底有哪些参数、怎么用、生成的文件都是啥?」—— 这篇把 goctl model 的 mysql / pg / mongo 三类数据源、每个 flag 的含义与默认值、典型命令组合、以及生成出来的每一个文件逐一点清。配命令速查表,适合直接贴终端用。
它不建表(呼应 建表与 Model 流程),只根据「DDL 文件」或「活的数据库连接」批量产出 model 包。
命令形态是 goctl model <数据源> <子命令>:数据源有 mysql / pg / mongo;mysql 下又有两条子命令——ddl(从 SQL 文件生成)和 datasource(从已建好的库反查生成)。两条路产物完全一样,区别只在信息源。两篇相邻主题:建表与 Model 流程、后端开发完整流程。
记住这张图,就知道该用哪条命令。
goctl model mysql ddl适合「表结构已经写成 .sql 文件」的场景,文件可纳入版本管理。
goctl model mysql ddl \ --src user.sql \ # 必填:DDL 文件(支持 glob 模式 *.sql) --dir ./model \ # 输出目录,默认 ./model --cache # 可选:生成 Redis 缓存代码
| 参数 | 简写 | 默认 | 必填 | 作用 |
|---|---|---|---|---|
--src | -s | — | 必填 | DDL 文件路径,或 glob 模式(*.sql、./sql/*.sql)。可传多个文件 / 多个 --src |
--dir | -d | ./model | 可选 | 生成代码的输出目录,目录不存在会自动创建 |
--cache | -c | false | 可选 | 是否生成带 Redis 缓存的 Model(主键 / 单字段唯一索引查询自动加缓存) |
--style | gozero | 可选 | 生成文件命名风格:gozero(连写小写)/ go_zero(蛇形下划线)等,见 --style 区别 | |
--idea | false | 可选 | 生成 IDEA 插件兼容格式(老式 goctl idea 插件用,日常基本不用) | |
--database | --db | — | 可选 | 指定数据库名。当 DDL 里没写库名、或一份 SQL 跨多个库生成时用 |
--home | — | 可选 | 本地模板目录;自定义生成代码风格用(与 --remote 互斥,同时设以 remote 为准) | |
--remote | — | 可选 | 远程 git 模板仓库地址(如 https://github.com/zeromicro/go-zero),用于拉取自定义模板 | |
--branch | master | 可选 | 远程模板的分支名(配 --remote 用) | |
--force | 版本相关 | 可选 | 较新版本支持:目标文件已存在时直接覆盖、不弹确认。老版本需手动删旧文件 |
--src 支持 glob 模式:--src ./*.sql 一次吃下当前目录所有 SQL;--src user.sql order.sql 多个文件也可。但 goctl 仍不执行建表——它只「读」SQL 里的 CREATE TABLE 来推结构,表得你自己先 mysql < user.sql 落到库里(或交给迁移工具)。goctl model mysql datasource适合「表已经在数据库里了」,连上去直接按表名生成,连 SQL 文件都不用准备。
goctl model mysql datasource \ --url "root:password@tcp(127.0.0.1:3306)/test" \ # 必填:数据源 --table user \ # 必填:表名(支持逗号分隔、glob) --dir ./model \ # 可选:输出目录 --cache # 可选:带缓存
| 参数 | 简写 | 默认 | 必填 | 作用 |
|---|---|---|---|---|
--url | — | 必填 | 数据源连接串,格式 user:password@tcp(host:port)/dbname。需有该库的 读表结构权限(SELECT 元信息) | |
--table | -t | — | 必填 | 表名。支持 逗号分隔(user,order)与 glob 模式(user_*);可多次 --table |
--dir | -d | ./model | 可选 | 输出目录 |
--cache | -c | false | 可选 | 生成带 Redis 缓存的 Model(同 ddl) |
--style | gozero | 可选 | 文件命名风格(同 ddl) | |
--idea | false | 可选 | IDEA 插件兼容格式(同上,基本不用) | |
--home / --remote / --branch / --force | — | 可选 | 模板自定义 / 覆盖,含义与 ddl 完全一致 |
--table user,order 一次生成两张;glob:--table "user_*" 吃掉所有 user_ 前缀表。两种可混用。--tables 参数——多表用 --table 的逗号分隔或多次 --table 表达,或 glob 模式一次性匹配。网上有些旧资料写 --tables,以官方 -h 输出为准。goctl 也支持,但形态略有不同(都是 datasource 反查,没有 ddl 子命令)。
goctl model pg datasourcegoctl model pg datasource \ --url "postgres://user:pass@127.0.0.1:5432/test?sslmode=disable" \ --table users \ # 表名;pg 有 schema 概念,默认 public --dir ./model \ --cache # pg 同样支持缓存(主键/唯一索引)
pg 子命令几乎复用 mysql 的参数(--url --table --dir --cache --style),连接串换成 Postgres 格式;没有 ddl 子命令,只能从活库生成。
goctl model mongo datasourcegoctl model mongo datasource \ --url "mongodb://127.0.0.1:27017" \ --table articles \ # 集合名 --dir ./model \ --style gozero
Mongo 是文档库,没有「表 / 缓存」概念,因此无 --cache;生成的是基于 core/stores/mongo 的文档增删改查。参数随版本略有差异,以 goctl model mongo datasource -h 为准。
goctl model pg datasource -h / goctl model mongo datasource -h 看当前版本真实参数,别照搬 mysql 的 flag。无论 ddl 还是 datasource,--dir 下都会冒出这批文件。理解角色才不会手改错地方。
| 文件 | 内容 | 重生成会覆盖吗 |
|---|---|---|
types.go | 每个表一个结构体,字段带 db:"create_time" 标签;snake_case 列自动对应 CamelCase 字段 | 会,按表结构刷新 |
vars.go | 缓存 key 前缀(cacheUserPrefix 等)+ 表名常量。开 --cache 才有缓存前缀,否则只有表名 | 会 |
errors.go | ErrNotFound——查不到记录时返回的错误 | 会 |
usermodel.go | 定义 UserModel 接口、声明 customUserModel 内嵌 defaultUserModel;你写的自定义查询方法放这里 | 接口签名刷新;手写方法保留 |
usermodel_gen.go | Insert / FindOne / FindOneByName / Update / Delete 等基础 CRUD 的真实实现 + 缓存逻辑,全在文件里 | 会,整个文件被重写 |
生成规则(决定「自带哪些方法」)
FindOne / Insert / Update / Delete。KEY idx_xxx(col) 额外生成 FindOneByName 之类;索引写得越全,自带查询越多。usermodel.go,千万别写进 usermodel_gen.go——下次重跑 goctl 整个文件被覆盖,代码瞬间消失。约定:生成的归 _gen.go,手写的归 usermodel.go。直接贴终端对照用。⊕=必填,○=可选。
| 参数 | 简写 | 默认 | ddl | datasource | 含义 |
|---|---|---|---|---|---|
--src | -s | — | ⊕ | DDL 文件 / glob 模式 | |
--url | — | ⊕ | 数据源连接串 | ||
--table | -t | — | ⊕ | 表名(逗号 / glob / 多次) | |
--dir | -d | ./model | ○ | ○ | 输出目录 |
--cache | -c | false | ○ | ○ | 生成 Redis 缓存代码 |
--style | gozero | ○ | ○ | 文件命名风格 | |
--idea | false | ○ | ○ | IDEA 插件兼容 | |
--database | --db | — | ○ | 指定库名(ddl 跨库用) | |
--home | — | ○ | ○ | 本地模板目录 | |
--remote | — | ○ | ○ | 远程模板仓库 | |
--branch | master | ○ | ○ | 远程模板分支 | |
--force | 版本相关 | ○ | ○ | 覆盖已存在文件不询问 |
--dir --cache --style --idea --home --remote --branch --force。差异只在信息源相关的必填项——ddl 要 --src,datasource 要 --url + --table。从「第一次生成」到「加表 / 改表后重生成」。
goctl model mysql ddl --src ./*.sql --dir ./internal/model --cache --style gozero
goctl model mysql datasource \
--url "root:123456@tcp(127.0.0.1:3306)/test" \
--table user,order \
--dir ./internal/model \
--cache
pay 表,补生成goctl model mysql datasource \
--url "root:123456@tcp(127.0.0.1:3306)/test" \
--table pay --dir ./internal/model --cache
新表文件会加进来,旧表文件不受影响(已手改的 usermodel.go 自定义方法保留)。
user 加了一列,重生成# 老版本先删旧文件,再生成;新版本加 --force 直接覆盖 goctl model mysql datasource \ --url "root:123456@tcp(127.0.0.1:3306)/test" \ --table user --dir ./internal/model --cache --force
_gen.go 和 types.go,但只要你的自定义逻辑在 usermodel.go 就安全。| 坑 | 现象 | 正确做法 |
|---|---|---|
| 以为 goctl 建表 | 连空库生成报「表不存在」 | 先建表(SQL / 迁移工具),再生成代码 |
开 --cache 却没配 Redis | 启动报错缺 CacheRedis | config 加 CacheRedis redis.RedisConf 并配地址(呼应 Model 流程·缓存) |
| datasource 权限不够 | 连库成功但读不到表结构 | 用有 information_schema 读权限的账号 |
| 忘了加二级索引 | 没有 FindOneByXxx | 建表时把常用查询列写成 KEY idx_xxx |
手改 _gen.go | 重生成后代码消失 | 自定义只写 usermodel.go |
| 照搬 mysql 参数到 pg/mongo | flag 报错 | 各数据源先跑 -h 看真实参数 |
都是 goctl 的子命令,但「信息源」与「必填项」不同。
| 命令 | 信息源 | 必填项 | 产出 |
|---|---|---|---|
goctl model mysql ddl | .sql 文件 | --src | model 包(数据访问) |
goctl model mysql datasource | 活库 | --url --table | model 包(数据访问) |
goctl api go | .api 文件 | --api | handler/logic/types/svc 骨架 |
goctl rpc protoc | .proto 文件 | --src --go_out | pb.go / zrpc 服务端客户端 |
记牢:goctl model 不建表,只「读表生成代码」;ddl 吃 SQL 文件、datasource 吃活库;两套公共参数(dir/cache/style/idea/home/remote/branch/force)完全一样;产物是 types/vars/errors/usermodel.go/usermodel_gen.go 五个文件,自定义逻辑写 usermodel.go。