Gorm gen
Contents
Gorm gen
参考链接:
- https://nickxu.me/2023/03/29/GORM%E7%9A%84GEN%E6%A8%A1%E5%BC%8F%E5%88%9D%E4%B8%8A%E6%89%8B/
- https://www.liwenzhou.com/posts/Go/gen/
示例代码:
Gen是一个基于GORM的安全ORM框架,其主要通过代码生成方式实现GORM代码封装。使用Gen框架能够自动生成Model结构体和类型安全的CRUD代码,极大提升CRUD效率。
Gen介绍
Gen是由字节跳动无恒实验室与GORM作者联合研发的一个基于GORM的安全ORM框架,主要通过代码生成方式实现GORM代码封装。
Gen框架在GORM框架的基础上提供了以下能力:
- 基于原始SQL语句生成可重用的CRUD API
- 生成不使用
interface{}
的100%安全的DAO API - 依据数据库生成遵循GORM约定的结构体Model
- 支持GORM的所有特性
简单来说,使用Gen框架后我们无需手动定义结构体Model,同时Gen框架也能帮我们生成类型安全的CRUD代码。
更多详细介绍请查看Gen官方文档。
此外,Facebook开源的ent也是社区中常用的类似框架,大家可按需选择使用。
Gen 使用
go get grom.io/gen
在项目根目录新建 model
文件夹,然后创建 model.go
package model
type Student struct {
Id int
Name string
TeacherID int
}
type Teacher struct {
Id int
Name string
// has many
Student []Student
}
然后使用go 生成代码
创建cmd/gen/generate.go
package main
import (
"github.com/root/genc/model"
"gorm.io/gen"
)
//// Dynamic SQL
//type Querier interface {
// // SELECT * FROM @@table WHERE name = @name{{if role !=""}} AND role = @role{{end}}
// FilterWithNameAndRole(name, role string) ([]gen.T, error)
//}
func main() {
g := gen.NewGenerator(gen.Config{
OutPath: "../../query",
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
})
// gormdb, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"))
//g.UseDB(gormdb) // reuse your gorm db
// Generate basic type-safe DAO API for struct `model.User` following conventions
g.ApplyBasic(model.Student{}, model.Teacher{})
// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`
//g.ApplyInterface(func(Querier) {}, model.User{}, model.Company{})
// Generate the code
g.Execute()
}
运行命令 go run cmd/gen/generate.go
[root@Sugar genc]🐳 go run cmd/gen/generate.go
2023/11/28 01:10:21 Start generating code.
2023/11/28 01:10:21 generate query file: /Users/root/github/genc/query/students.gen.go
2023/11/28 01:10:21 generate query file: /Users/root/github/genc/query/teachers.gen.go
2023/11/28 01:10:21 generate query file: /Users/root/github/genc/query/gen.go
2023/11/28 01:10:21 Generate code done.
server main文件
cmd/sugar/sugar.go
package main
import (
"fmt"
"github.com/glebarez/sqlite"
"github.com/root/genc/model"
"github.com/root/genc/query"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
func main() {
// dsn := "root:12345678@tcp(127.0.0.1:3306)/gorm_learning?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{
DisableForeignKeyConstraintWhenMigrating: true,
NamingStrategy: schema.NamingStrategy{
SingularTable: true, // 设置创建表名时不使用复数
},
})
if err != nil {
panic(err)
}
err = db.AutoMigrate(&model.Student{}, &model.Teacher{})
if err != nil {
panic(err)
}
query.SetDefault(db)
// 增
student1 := model.Student{Name: "student1"}
student2 := model.Student{Name: "student2"}
student3 := model.Student{Name: "student3"}
_ = query.Student.Create(&student1, &student2, &student3)
teacher1 := model.Teacher{Name: "teacher1"}
_ = query.Teacher.Create(&teacher1)
// 删
_, _ = query.Student.Where(query.Student.Id.Eq(3)).Delete()
// 改
_, _ = query.Student.Where(query.Student.Id.Eq(2)).Update(query.Student.Name, "student2_new")
// 查
student, _ := query.Student.Where(query.Student.Id.Eq(1)).Take()
teacher, _ := query.Teacher.Where(query.Teacher.Id.Eq(1)).Take()
fmt.Println(student) // {1 student1 0}
fmt.Println(teacher) // {1 teacher1 []}
// 关联
_ = query.Teacher.Student.Model(&teacher1).Append(&student1, &student2)
teacher, _ = query.Teacher.Preload(query.Teacher.Student).Where(query.Teacher.Id.Eq(1)).Take()
fmt.Println(teacher) // {1 teacher1 [{1 student1 1} {2 student2_new 1}]}
fmt.Println(query.Student.TableName())
fmt.Println(query.Teacher.TableName())
}
运行主服务
[root@Sugar genc]🐳 go run cmd/sugar/main.go
&{1 student1 1}
&{1 teacher1 []}
&{1 teacher1 [{1 student1 1} {2 student2_new 1}]}
student
teacher
更新字段使用对比
GLOBAL_DB.Model(&Student{}).Where("ID = ?", 2).Update("Name", "student2_new")
query.Student.Where(query.Student.Id.Eq(2)).Update(query.Student.Name, "student2_new")