这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
Gorm简介
Gorm是服务于Golang的一个ORM库,拥有活跃的社区 ,gorm的作者是中国人,因此它拥有完整的中文文档
什么是ORM?
Object-Relationl Mapping,即对象关系映射,这里的Relationl指的是关系型数据库。简单来说,ORM是一种数据库操作辅助工具,可以使go结构体和数据库之间产生映射,让我们对数据库的关系,表的内容,直观地体现在结构体上。
ORM如何连接数据库?
1.导入gorm
2.导入gorm驱动
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
3.使用open链接 得到数据库操作对象(以Mysql为例)
func main() {
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" //DataSource Name
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
这样得到的db就是数据库操作对象
第二种链接方式 ,可以配置除了DNS之外的附加属性 ①DefaultStringSize
//第二种方式 可以配置除了DNS之外的其他属性
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:自己的密码@tcp(127.0.0.1:3306)/目标数据库名称?charset=utf8mb4&parseTime=True&loc=Local", // DSN data source name
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{
SkipDefaultTransaction: false,
DisableForeignKeyConstraintWhenMigrating: true, //跳过物理外键的创建,提高性能
NamingStrategy: schema.NamingStrategy{
TablePrefix: "hex_", // 表名前缀,`User` 的表名应该是 `t_users`
SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
},
})
此外gorm还支持连接池的方式创建数据库连接
//GORM 使用 [database/sql](https://pkg.go.dev/database/sql) 来维护连接池
sqlDB, err := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
创建数据库表(迁移)
1使用AutoMigrate 自动创建表,以User结构体为例
type User struct {
Name string
}
_ = db.AutoMigrate(&User{})
fmt.Println(err)
输出结果为nil说明创建表成功
注意 使用AutoMigrate 会自动添加缺少的外键,约束,列和索引,并且会更改现有列的类型(如果其大小、精度、是否为空可更改)。
有时候我们不需要添加物理外键或者是索引来提高性能,可以在上面的第二种配置数据库的方法中开启跳过自动添加的功能
2使用Migrator接口
GORM 提供了 Migrator 接口,该接口为每个数据库提供了统一的 API 接口,可用来为数据库构建独立迁移,此外该接口该提供了其他方法比如查询数据库是否存在:
migrator := db.Migrator()
migrator.CreateTable(&User{})
hasByStruct := migrator.HasTable(&User{}) //根据需要迁移的结构体进行查找
hasByName := migrator.HasTable("hex_user") //根据表名进行查找
fmt.Println("根据结构体查找是否存在", hasByStruct)
fmt.Println("根据表名称查找是否存在", hasByName)
在我自己第一次尝试创建的时候遇到了一个问题导致创建失败
后来找到了原因,是因为结构体内部的字段名称,必须首字母大写,例如name可以写成Name或者NAME,但是如果是name(全部小写),就会无法识别。