文章目錄
- 建項目
- 建庫建表
- main.go
- user.go
- company.go
- 生成效果
- (更進一步)自定義dynamic SQL實踐
官方地址:https://gorm.io/zh_CN/gen/index.html
以mysql為例
建項目
go mod init 項目名稱
go mod tidy
建庫建表
建數據庫demo
,正常排序和字符集utf8mb4
即可
在數據庫內建表,可參考如下代碼:
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100),role VARCHAR(50),age INT
);CREATE TABLE companies (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100)
);
main.go
安裝gen
go get -u gorm.io/gen
前大半部分為官方快速入門的代碼,后嘗試創建用戶的部分可自行調整。
package mainimport ("context""gorm-gen-demo/model""gorm-gen-demo/query""gorm.io/driver/mysql""gorm.io/gen""gorm.io/gorm""log"
)// 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() {dsn := "user:password@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local" //替換成自己的,此句兩次執行代碼均保留// ------------------------------- 官方代碼gormdb, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {log.Fatalf("failed to connect database: %v", err)}g := gen.NewGenerator(gen.Config{OutPath: "query",Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate model})g.UseDB(gormdb) // reuse your gorm db// Generate basic type-safe DAO API for struct `model.User` following conventionsg.ApplyBasic(model.User{})// 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 codeg.Execute()// ------------------------------------上下兩段代碼可分兩次執行db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})query.SetDefault(db)user := model.User{Name: "Modi", Age: 18}u := query.Userctx := context.Background()err = u.WithContext(ctx).Create(&user)if err != nil {log.Fatalf("failed to create user: %v", err)}}
其中嘗試創建用戶部分,query.SetDefault(db)
句不可少,否則會報錯panic: runtime error: invalid memory address or nil pointer dereference
接下來兩個文件都是在根目錄下的model文件夾下新建,定義數據庫表結構所用
user.go
package modeltype User struct {ID intName stringRole stringAge int
}
company.go
package modeltype Company struct {ID intName string
}
生成效果
(更進一步)自定義dynamic SQL實踐
如果添加了自定義注解的sql查詢,需要先gen生成,然后再調用自定義的函數查詢!否則會報錯,說不認識自定義的這個函數
unresovled
。
代碼:
// Dynamic SQL
type Querier interface {// SELECT * FROM @@table WHERE name = @name{{if role !=""}} AND role = @role{{end}}// FilterWithNameAndRole(name, role string) ([]gen.T, error)// 添加注解和函數注冊!!!//// SELECT * FROM @@table WHERE id=@idGetByID(id int) (gen.T, error) // returns struct and error
}// main中添加綁定!!!
g.ApplyInterface(func(Querier) {}, model.User{}) // 綁定的是User結構體,所以只會在user.gen.go里注冊和實現
寫好注解和函數,進行g.Execute()
,可以在user.gen.go里看到如下已經被注冊的函數:
進行調用查詢,添加代碼:
res, err := query.User.WithContext(context.Background()).GetByID(1)if err != nil {fmt.Printf("GetByID failed , err:%v\n", err)return}fmt.Printf("GetByID result : %v", res)
查詢結果:
第一遍生成,第二遍才是在調用
GetByID
這個新自定義函數