这是我参与「第五届青训营」伴学笔记创作活动的第十三天。
一:本堂课的重点内容
GORM的使用
二:详细知识点如下
1)概要
使用上主要是把 struct 类和数据库表进行映射,操作数据库时无需手写 sql。本质就是提供一组函数来帮助我们快速拼接 sql 语句,尽量减少 sql 的编写。
- 取数据逻辑:
从数据库读取的数据会先保存到预先定义的模型对象,然后我们就可以从模型对象得到我们想要的数据。
- 存数据逻辑:
存数据到数据库也是先新建一个模型对象,然后把数据保存到模型对象,最后把模型对象保存到数据库。
-
创建/更新时间
gorm 约定使用 struct 中的 CreatedAt 和 UpdatedAt 表示创建时间和更新时间,所以 gorm 在创建和更新时候会自动填充,如果想用其他变量名就可以在gorm:"autoCreateTime:milli和gorm:"autoUpdateTime:milli
默认情况下,GORM 会使用ID作为表的主键;
可以通过标签
gorm:"primaryKey"将某个字段设为主键;使用结构体名的 snake_case 作为表名, 譬如UserAssets,在数据库中为user_assets,表名结尾自动添加字母s,如单词以s结尾则不添加;
如果结构体名转为snake_case形式后的表格不存在,那么需显式指定表名,譬如db.Table("User").Create(user);
2)基本使用
在高并发中,为了提高数据库连接速度,避免重复连接数据库带来性能消耗,会常常使用数据库连接池来维护数据库连接。gorm 自带数据库连接池,只需要设置下数据库连接池参数即可。
func init() {
// 配置 dsn
// err
var err error
// 连接 mysql 获取 db 实例
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("连接数据库失败, error=" + err.Error())
}
// 设置数据库连接池参数
sqlDB, _ := db.DB()
// 设置数据库连接池最大连接数
sqlDB.SetMaxOpenConns(100)
// 连接池最大允许的空闲连接数,如果没有sql任务需要执行的连接数大于20,超过的连接会被连接池关闭
sqlDB.SetMaxIdleConns(20)
}
// 获取 gorm db,其他包调用此方法即可拿到 db
// 无需担心不同协程并发时使用这个 db 对象会公用一个连接,因为 db 在调用其方法时候会从数据库连接池获取新的连接
func GetDB() *gorm.DB {
return db
}
3)Gorm目前支持mysql,sqlserver,postgreSQL,SQLlite.Gorm通过驱动来连接数据库,如果需要连接其他类型的数据库,可以通过复用/自行开发驱动。
4)使用注意事项
5)事务
gorm提供了begin,commit,rollback方法用于使用事务。
gorm提供了transaction方法用于自动提交事务,避免用户漏写commit,rollback.
6)性能提高
对于增删改,未来保证数据的完整性,GORM会将它们封装在事务内运行,但这会降低性能,可以使用skipdefaultTransaction关闭默认事务。使用prepareStmt预存预编译语句可以提高后续调用的速度,本机测试提高大约35%左右。
三、课后个人总结
使用过程中的一些坑
1,.Count()函数在特定情况下返回的记录数量不是正确的值
解决办法:调整语句,查询多次,分别查询
2,deleted_at是Model结课体的既定字段,删除记录时表的该条记录不会实际删除,而是deleted_at置为非空(删除操作时的时间),此时如果你的表结构设计的有些纰漏,那么功能就会有bug,如ID字段使用未来可能继续出现的值时。
解决办法:重新调整列功能及值,增加列
3,当对含有布尔值的结构体进行修改操作时,且修改到了这一列,那么此时使用.Update(&结构体变量)是不生效的,不生效体现为修改为true时能正常修改,修改为false时数据库中值不变。那么这种情况怎么解决?看上面列举的修改操作的几种情况就可以了。
四、引用参考
github 地址:github.com/go-gorm/gor…