Skip to content

Model Generation

goctl model generates type-safe CRUD code with no ORM, no reflection — just plain Go functions backed by sqlx for relational databases and the official driver for MongoDB.

Terminal window
goctl model mysql ddl [flags]
FlagDescription
-srcPath to the .sql DDL file (required)
-dirOutput directory (required)
-cacheWrap with Redis cache layer
-styleFile naming style: gozero | go_zero | goZero
-homeCustom template directory
Terminal window
goctl model mysql ddl \
-src schema.sql \
-dir ./internal/model \
-cache
Terminal window
goctl model mysql datasource [flags]
FlagDescription
-urlMySQL DSN (required)
-tableComma-separated table names or "*" for all
-dirOutput directory (required)
-cacheWrap with Redis cache layer
-styleFile naming style
Terminal window
goctl model mysql datasource \
-url "root:pass@tcp(127.0.0.1:3306)/mydb" \
-table "user,order" \
-dir ./internal/model \
-cache

For a user table, the generated interface is:

type UserModel interface {
Insert(ctx context.Context, data *User) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*User, error)
FindOneByUsername(ctx context.Context, username string) (*User, error)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id int64) error
Trans(ctx context.Context, fn func(context.Context, sqlx.Session) error) error
}
  • Unique index columns (like username above) automatically generate a FindOneBy<Column> method.
  • The Trans method wraps multiple operations in a database transaction.

Terminal window
goctl model pg datasource [flags]
FlagDefaultDescription
-urlPostgreSQL DSN (required)
-tableTable name(s)
-schemapublicPostgreSQL schema
-dirOutput directory (required)
-cachefalseAdd Redis cache layer
-stylegozeroFile naming style
Terminal window
goctl model pg datasource \
-url "postgres://root:pass@localhost:5432/mydb?sslmode=disable" \
-table "users,products" \
-dir ./internal/model

The generated code is nearly identical to MySQL — same CRUD interface, same cache integration, different SQL placeholder syntax ($1 vs ?).


Terminal window
goctl model mongo [flags]
FlagDefaultDescription
-typeGo type name for the document (required)
-dirOutput directory (required)
-cachefalseAdd Redis cache layer
-easyfalseGenerate a minimal no-frills interface
-stylegozeroFile naming style
-home~/.goctlCustom template directory
Terminal window
goctl model mongo -type Article -dir ./internal/model -cache

Generated files:

internal/model/
├── articlemodel.go # interface + New() constructor
├── articlemodelgen.go # generated CRUD implementation
└── vars.go # error variables

When -cache is passed, the generated model wraps every FindOne and FindOneBy* read in a two-level cache:

  1. Local memory cache (LRU, 1000 entries, 60-second TTL)
  2. Redis (configurable TTL)

Cache invalidation happens automatically on Update and Delete.

internal/svc/servicecontext.go
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
func NewServiceContext(c config.Config) *ServiceContext {
sqlConn := sqlx.NewMysql(c.DataSource)
cacheConf := cache.CacheConf{
{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"},
}
return &ServiceContext{
Config: c,
UserModel: model.NewUserModel(sqlConn, cacheConf),
}
}

Override any generated file by editing the corresponding template:

Terminal window
goctl template init # copies defaults to ~/.goctl/
ls ~/.goctl/model/ # insert.tpl, find-one.tpl, update.tpl, delete.tpl, ...
# Edit a template
vim ~/.goctl/model/insert.tpl
# Regenerate using your customised templates
goctl model mysql ddl \
-src schema.sql \
-dir ./internal/model \
-home ~/.goctl