Gen allows generate fully-type-safe idiomatic Go code from Raw SQL, it uses annotations on interfaces, those interfaces could be applied to multiple models during code generation.
Not only your tuned SQL queries but also SQL snippets are allowed to be shared and reused, let’s take an example:
Raw SQL
type Querier interface { |
Run the above configuration program to generate the query interface codes for your
application. The following usage snippets share this preamble — your application
opens its own runtime *gorm.DB (a separate connection from the generator’s
schema DB above) and registers it with the generated package; ctx is defined
once:
import ( |
Two rules the generated code imposes:
- DIY methods are generated on the per-model DO type, and in the default
(context-aware) mode that type is reached through the model’sWithContext—query.User.WithContext(ctx).GetByID(10). Callingquery.User.GetByID(10)
directly does not compile unless you generate with theWithoutContextmode. - A
gen.Tresult is the model struct itself; write*gen.T,[]gen.Tor[]*gen.Tin the interface signature to change the generated result shape
((result *model.User),(result []model.User),(result []*model.User)).
Generated-file layout
g.Execute() writes one <model>.gen.go per applied model into OutPath
(e.g. query/users.gen.go), plus one entry file (gen.go by default, name set
by Config.OutFile). The entry file defines Use(db) returning *Query, and —
when the WithDefaultQuery mode is enabled — the package-level Q and
per-model variables (query.User) wired by query.SetDefault(db).
Code Snippets
Code Snippets are usually used with the DAO interface together
type Querier interface { |
Usage (same shared preamble as above — runtime gorm.Open + query.SetDefault(db)
- defined
ctx; repeated here for readability):
userMap, err := query.User.WithContext(ctx). |
The generated snippet method feeds its SQL fragment to the underlying GORM
session as an additional Where condition, so conditions you chained before it
are kept (AND-combined), and it is perfectly fine to call the snippet on its own:
userMap, err := query.User.WithContext(ctx).FindByNameAndAge("modi", 18) |
Generated code for the snippet above (note it queries into the gen.M map you
declared as the return type):
func (u userDo) FindByNameAndAge(name string, age int) (result map[string]interface{}, err error) { |
More control
Gen support conditionally annotations and customize the returning results, refer Annotation to learn more