Gorm与Gorm Gen实践
众所周知,DAO层是后端服务的重要组成部分,在学习Go 语言工程实践之测试课程时,老师给予了完整的源代码。看到老师们设计的DAO层,甚是羡慕。但是对于我这样刚接触GO语言的人来说,直接上手完成DAO层有些困难,于是便学习了Gorm Gen已实现自动化生成DAO层。
Gorm Gen简介
Gorm官方提供了一个可以自动生成数据库结构体的工具:Gen。
这个工具不仅仅可以用来生成数据表对应的模型文件,还提供了更加安全以及方便的API。
1.Gorm Gen安装
目前Gorm Gen在Gorm.io下,直接引入即可。不需要额外的安装。
2.配置数据库
Gorm Gen依赖配置好的数据库生成DAO层,官方文档中的数据库为SQLite,在这里我使用了MySql作为演示。数据库使用了Go 语言工程实践之测试课程中老师使用的数据库。
数据库模型如下图所示。
3.编写自动生成代码
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gen"
"gorm.io/gorm"
)
func main() {
// Initialize the generator with configuration
g := gen.NewGenerator(gen.Config{
OutPath: "./dal", // output directory, default value is ./query
ModelPkgPath: "./mode",
Mode: gen.WithDefaultQuery | gen.WithQueryInterface | gen.WithoutContext,
FieldNullable: true,
FieldCoverable: false,
FieldSignable: false,
FieldWithIndexTag: false, // generate with gorm index tag
FieldWithTypeTag: true, // generate with gorm column type tag
})
dsn := "root:1xxxxxxxx1@tcp(localhost:3306)/community?charset=utf8mb4&parseTime=True&loc=Local"
// Initialize a *gorm.DB instance
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
g.UseDB(db)
User := g.GenerateModel("user")
Post := g.GenerateModel("post")
Topic := g.GenerateModel("topic")
g.ApplyBasic(User, Post, Topic)
// Use the above `*gorm.DB` instance to initialize the generator,
// which is required to generate structs from db when using `GenerateModel/GenerateModelAs`
// Execute the generator
g.Execute()
}
在main
函数中,创建了一个Gorm-gen的代码生成器g
,并使用了gen.Config
结构来配置生成器的行为。配置项包括:
OutPath
:生成的代码输出目录,这里设置为./dal
,即当前目录下的dal
文件夹。ModelPkgPath
:指定模型的包路径,这里设置为./mode
,即当前目录下的mode
文件夹。Mode
:生成器的模式,这里使用了gen.WithDefaultQuery | gen.WithQueryInterface | gen.WithoutContext
,表示生成默认查询方法、查询接口方法,并且不使用Context(即不生成WithContext方法)。FieldNullable
:是否生成字段的可空标志,默认为true
,表示字段会生成为指针类型。FieldCoverable
:是否生成字段的Cover方法,默认为false
,Cover方法用于覆盖模型字段值。FieldSignable
:是否生成字段的Sign方法,默认为false
,Sign方法用于对字段值进行签名。FieldWithIndexTag
:是否生成Gorm的index标签,默认为false
,表示不生成index标签。FieldWithTypeTag
:是否生成Gorm的column类型标签,默认为true
,表示生成column类型标签。
接下来,定义了数据库连接字符串dsn
,用于连接到MySQL数据库。然后,通过gorm.Open
方法创建了一个Gorm数据库实例db
,并将其传递给生成器g
的UseDB
方法。这样,生成器就知道要连接到哪个数据库,并可以使用该数据库的信息来生成模型代码。
然后,通过g.GenerateModel
方法分别生成了三个模型:User、Post和Topic。这些模型对应着数据库中的三个表,并且包含了对应表的字段信息、查询方法等。
接着,通过g.ApplyBasic
方法为生成的三个模型应用基本的增删改查功能,这样生成的模型将具有基本的CRUD(Create, Read, Update, Delete)操作。
最后,通过g.Execute
方法来执行代码生成器,它会根据之前的配置和定义生成模型代码,并输出到指定的输出目录。
**对于gen.Config参数的解释,是我个人的理解,如有错误请批评指正。**由于我对Gorm的学习不足,因此无法确定gen.Config的参数在实际运行中会对数据库与Go程序产生何种影响。
4.测试生成的代码
func main() {
dsn := "root:1xxxxxxxx1@tcp(localhost:3306)/community?charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
dal.SetDefault(db)
u := &mode.User{
ID: 3,
Name: "张XX",
Level: 2,
CreateTime: time.Now(),
ModifyTime: time.Now(),
}
err := dal.User.Create(u)
if err != nil {
fmt.Println(err)
}
}
测试结果
总结
首先,GORM gen官方文档中的实例在Goland中无法运行,有报错。
第二点,ModelPkgPath生成的是struct,而OutPath中生成的是数据操作接口,但是如果忽略ModelPkgPath则不会生成struct,这导致dal中的函数出现错误,但是生成过程中没有提示,这一点很奇怪。目前官网与其他教程中均未使用这个参数。