初识Gorm与上手实践 | 青训营笔记

224 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第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)

在我自己第一次尝试创建的时候遇到了一个问题导致创建失败

image.png 后来找到了原因,是因为结构体内部的字段名称,必须首字母大写,例如name可以写成Name或者NAME,但是如果是name(全部小写),就会无法识别。

image.png