Gorm Gen
Contents
Gorm Gen
参考链接:https://www.liwenzhou.com/posts/Go/gen/
Gen是一个基于GORM的安全ORM框架,其主要通过代码生成方式实现GORM代码封装。使用Gen框架能够自动生成Model结构体和类型安全的CRUD代码,极大提升CRUD效率。
const DSN = "postgres://user:password@127.0.0.1:5432/hello?sslmode=disable&TimeZone=Asia/Shanghai&search_path=public"
func connectDB(dsn string) *gorm.DB {
db, err := gorm.Open(postgres.Open(dsn))
if err != nil {
panic(fmt.Errorf("connect db fail: %w", err))
}
return db
}
func main() {
// 指定生成代码的具体相对目录(相对当前文件),默认为:./query
// 默认生成需要使用WithContext之后才可以查询的代码,但可以通过设置gen.WithoutContext禁用该模式
g := gen.NewGenerator(gen.Config{
// 默认会在 OutPath 目录生成CRUD代码,并且同目录下生成 model 包
// 所以OutPath最终package不能设置为model,在有数据库表同步的情况下会产生冲突
// 若一定要使用可以通过ModelPkgPath单独指定model package的名称
OutPath: "data/query",
ModelPkgPath: "data/model",
// 生成 gorm 标签的字段类型属性
FieldWithTypeTag: true,
// 表字段可为 null 值时, 对应结体字段使用指针类型
FieldNullable: true,
// gen.WithoutContext:禁用WithContext模式
// gen.WithDefaultQuery:生成一个全局Query对象Q
// gen.WithQueryInterface:生成Query接口
Mode: gen.WithDefaultQuery,
})
// 通常复用项目中已有的SQL连接配置db(*gorm.DB)
// 非必需,但如果需要复用连接时的gorm.Config或需要连接数据库同步表信息则必须设置
g.UseDB(connectDB(DSN))
// 从连接的数据库为所有表生成Model结构体和CRUD代码
// 也可以手动指定需要生成代码的数据表
dataTypeMap := map[string]func(gorm.ColumnType) (dataType string){
"numeric": func(columnType gorm.ColumnType) string { return "decimal.Decimal" },
"int4": func(columnType gorm.ColumnType) string { return "int64" },
"int2": func(columnType gorm.ColumnType) string { return "int64" },
"serial4": func(columnType gorm.ColumnType) string { return "int64" },
}
g.WithDataTypeMap(dataTypeMap)
g.ApplyBasic(g.GenerateAllTable()...)
// 执行并生成代码
g.Execute()
表关联
// foreignKey: action 表中的字段,action表中的id
// references: user表中的字段,user表中的 action_id
action := g.GenerateModel("action")
user := g.GenerateModel("user",
gen.FieldRelate(field.HasMany, "actions", action,
&field.RelateConfig{
RelateSlicePointer: true,
GORMTag: field.GormTag{
"foreignKey": []string{
"ID",
},
"references": []string{
"ActionID",
},
},
},
),
)
基于索引的情况下批量更新或者新增
err = pa.WithContext(ctx).Clauses(
clause.OnConflict{
Columns: []clause.Column{
{Name: user.Code.ColumnName().String()},
},
TargetWhere: clause.Where{
Exprs: []clause.Expression{
clause.Expr{
SQL: "deleted_at = 0",
},
},
},
DoUpdates: clause.AssignmentColumns(cols),
},
).
CreateInBatches(items, 30)