Friendly & Safer GORM powered by Code Generation.
Install as a library:
go get gorm.io/gen@latest
Create a generator entry (recommended: cmd/gen/main.go):
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gen"
"gorm.io/gorm"
)
func main() {
db, err := gorm.Open(mysql.Open("dsn"), &gorm.Config{})
if err != nil {
panic(err)
}
g := gen.NewGenerator(gen.Config{
OutPath: "internal/dal/query",
Mode: gen.WithDefaultQuery | gen.WithQueryInterface, // enable query.SetDefault(db)
})
g.UseDB(db)
g.ApplyBasic(g.GenerateAllTable()...)
g.Execute()
}
Run generation:
go run ./cmd/gen
If you enabled WithDefaultQuery, initialize once at startup:
package main
import (
"context"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"your/module/internal/dal/query"
)
func main() {
db, err := gorm.Open(mysql.Open("dsn"), &gorm.Config{})
if err != nil {
panic(err)
}
query.SetDefault(db)
u := query.User
_, _ = u.WithContext(context.Background()).
Where(u.Age.Gt(18)).
Find()
}
query.SetDefault(db) only needs to run once (e.g. during service startup). After that, use query.<Table> directly.
If you don’t want a global default, skip WithDefaultQuery and use:
q := query.Use(db)
_, _ = q.User.WithContext(ctx).Where(q.User.Age.Gt(18)).Find()
More runnable examples: examples
Gen has one generator entry point (gen.NewGenerator(gen.Config{...})). The main knobs you typically use are:
Config.Mode flags (WithDefaultQuery, WithoutContext, WithQueryInterface, WithGeneric)g := gen.NewGenerator(gen.Config{
OutPath: "internal/dal/query",
Mode: gen.WithDefaultQuery | gen.WithQueryInterface,
FieldNullable: true,
FieldCoverable: true,
FieldWithIndexTag: true,
})
g.UseDB(db)
g.ApplyBasic(g.GenerateAllTable()...)
g.Execute()
Define an interface with SQL comments/templates:
package dal
import "gorm.io/gen"
type UserMethods interface {
// FindByID
//
// SELECT * FROM users WHERE id=@id
FindByID(id int) gen.T
// FindByOptionalName
//
// SELECT * FROM users
// {{where}}
// {{if name != ""}}
// name=@name
// {{end}}
// {{end}}
FindByOptionalName(name string) []gen.T
}
Bind the interface to a generated model/table:
g.ApplyInterface(func(m UserMethods) {}, g.GenerateModel("users"))
Template syntax reference exists in the test corpus: method.go.
Generics is not a separate “workflow”; it changes the generated query API surface for stronger typing.
g := gen.NewGenerator(gen.Config{
OutPath: "internal/dal/query",
Mode: gen.WithDefaultQuery | gen.WithGeneric,
})
Keep code generation isolated and reproducible (works well with go:generate and CI).
your-repo/
internal/
dal/
model/ # generated model structs (optional)
query/ # generated query (+ DIY methods)
cmd/
gen/
main.go # generator entry (checked in)
If you prefer a CLI workflow, use GenTool:
@riverchu @iDer @qqxhb @dino-ma
You can help to deliver a better GORM/Gen, check out things you can do
Released under the MIT License