青训营笔记 | 青训营

53 阅读4分钟

GORM

连接数据库

GORM会维护一个连接池,它会在初始化数据库之后自动管理所有的数据库连接。这意味着使用者不需要手动关闭数据库连接,GORM会在需要时从连接池中获取连接,并在使用完毕后将其返回给连接池。这样可以提高数据库连接的效率,并且减少了使用者的负担。

创建

模型定义 
type User struct {
ID int64 Name string Age int64
} 
使用使用NewRecord()查询主键是否存在,主键为空使用Create()创建记录:
user := User{Name: "xxx", Age: 18} 
db.NewRecord(user) // 主键为空返回`true`
db.Create(&user) // 创建user

默认值

可以通过 tag 定义字段的默认值,比如:

type User struct { 
ID int64 
Name string `gorm:"default:'xxx'"` 
Age int64 }

在Gorm中,当创建记录时,生成的SQL语句会排除没有值或值为零值的字段。这意味着如果某个字段没有被赋值或者被赋值为零值(如0、false、空字符串等),那么该字段不会出现在生成的SQL语句中。

当将记录插入到数据库后,Gorm会从数据库加载那些字段的默认值。这是因为数据库在插入记录时,可能会对某些字段设置了默认值,而Gorm会在加载记录时将这些默认值加载到对应的字段中。

需要注意的是,Gorm只会加载那些在数据库中有默认值的字段,如果某个字段在数据库中没有设置默认值,则Gorm会将其加载为该字段类型的零值。

总结起来,Gorm在创建记录时会排除没有值或值为零值的字段,而在从数据库加载记录时会加载那些字段的默认值。

var user = User{Name: "", Age: 99} 
db.Create(&user)

上面代码实际执行的SQL语句是INSERT INTO users("age") values('99');,排除了零值字段Name,而在数据库中这一条数据会使用设置的默认值xxx作为Name字段的值。

所有字段的零值, 比如0, "",false或者其它零值,都不会保存到数据库内,但会使用他们的默认值。

如果想避免这种情况,可以考虑使用指针或实现 Scanner/Valuer接口,比如:

使用指针方式实现零值存入数据库

// 使用指针 
type User struct {
ID int64 
Name *string `gorm:"default:'xxx'"`
Age int64 } 
user := User{Name: new(string), Age: 18))} 
db.Create(&user) // 此时数据库中该条记录name字段的值就是''

使用Scanner/Valuer接口方式实现零值存入数据库

// 使用 Scanner/Valuer 
type User struct { 
ID int64 
Name sql.NullString `gorm:"default:'xxx'"` // sql.NullString 实现了Scanner/Valuer接口 
Age int64 
} 
user := User{Name: sql.NullString{"", true}, Age:18}
db.Create(&user) // 此时数据库中该条记录name字段的值就是''

map[string]interface{}:实现字符串类型的map接口

路由组

在Go语言中,路由组是一种将多个相关的路由路径进行组织和管理的方式。路由组可以帮助开发者更好地组织和维护应用程序的路由逻辑。

使用路由组,可以将具有相同前缀的路由路径进行分组,并在组级别上应用中间件或其他共享逻辑。这样可以提高代码的可读性和可维护性,同时也可以减少代码的重复。

在Go语言中,常用的路由组实现方式是使用第三方库,如Gin、Echo等。这些库提供了一套简洁而强大的API,使得创建和管理路由组变得非常简单。

通过使用路由组,可以将应用程序的路由逻辑划分为不同的模块或功能区域,并为每个模块或功能区域创建一个独立的路由组。这样可以提高代码的可维护性,并使得不同模块之间的路由逻辑更加清晰和可理解。

r := gin.Default() 
//引用静态文件
r.Static("/static", "./static") 
//引用模板文件
r.LoadHTMLGlob("templates/*") 
//设置路由 r.GET("/", controller.IndexHandler)
v1 := r.Group("v1")
{ 
todo := v1.Group("todo")
//增加某个todo 
todo.POST("", controller.AddTodo) 
//查看全部todo 
todo.GET("", controller.GetTodoList) 
//修改某个todo 
todo.PUT(":id", controller.EditTodo)
//删除某个todo 
todo.DELETE(":id", controller.DeleteTodo)
} 
// GET / 
// GET /v1/todo
// POST /v1/todo
// PUT /v1/todo/:id 
// DELETE /v1/todo/:id