青训营后端笔记2-GORM 使用指南 | 豆包MarsCode AI刷题

21 阅读5分钟

GORM 是 Go 语言的一个强大的 ORM(对象关系映射)库,可以让开发者使用 Go 语言优雅地操作数据库。GORM是一个已经迭代了10年以上的功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源拓展。

本文将介绍如何使用 GORM 连接数据库并实现基本的增删改查操作,同时结合个人分析讨论其设计特点和使用感受。

使用GORM连接mysql数据库

定义GROM model

即定义表结构Product,表中含有string类型的Codeuint类型的Price

type Product struct {
    Code string
    Price uint
}

定义结构体时也可以使用default标签,为字段定义默认值

type User struct {
    ID int64
    Name string `gorm:"default: galeone"`
    Age int64 `gorm:"default: 18"`

接下来为 model 定义表名,为Product创建一个TableName()方法返回一个内容为productstring,用于获取结构体的表名。

func (p Product) TableName() string {
    return "product"
}

连接数据库

本文以连接mysql数据库为例。在连接mysql数据库之前,需要定义一个DSN,它是用于描述连接数据库所需信息的字符串。在使用 Go 的 go-sql-driver/mysql 驱动连接 MySQL 数据库时,DSN 是必须提供的参数,它包含了数据库的用户名、密码、地址、数据库名及其他可选配置项。 DSN 的基本格式如下:

[用户名]:[密码]@tcp([主机]:[端口])/[数据库名]?[参数列表]

连接数据库的代码

func main(){
    dsn := "user:pass@tcp (127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(
        mysql.Open(dsn), &gorm.Config{})//&gorm.Config{}用于传递自定义配置
    if err != nil{
        panic("failed to connect database")
    }

GORM连接数据库后的基本操作

1.创建数据

此处创建一条Code="D42", Price=100 的记录。除此之外,创建数据时还可以一次性创建多条数据,只不过创建一条数据时是传入一个变量,创建多条数据时是传入一个切片或数组。

// 创建数据
db. Create(&Product{Code: "D42", Price: 100})

如果创建记录时存在冲突的可能性,可以使用clause.OnConflict处理冲突,下方给出一组在发生冲突时不进行任何处理的示例代码

p := &Product{Code: "D42", ID:1}
db.Clauses(clause.OnConflict{DoNothing: true}).Create(&p)

2.查询数据

首先通过var声明一个product变量,用来保存查询的结果。需要注意的地方是传入的变量必须是一个指针,因为查询结果会返写到结构体中,这样才能保证结果能够写入到product。查询方式可分为按主键查询按条件查询

// 查询数据
var product Product
//First只能查询一条记录
db.First(&product, 1) // 根据主键查询 ID 为 1 的记录 
db.First(&product, "code = ?", "D42") // 根据字段值查询记录

使用First时,需要注意查询不到数据时,会返回ErrRecordNotFound,容易造成程序停止。而使用Find查询多条数据,查询不到数据时,返回的是一个空数组,因此更多使用Find查询。

var products []Product
result := db.Find(&products)//返回表中的所有记录
result := db.Where("price > ?", 100).Find(&products)//返回price大于100的所有记录
result := db.Where("price > ? AND code = ?", 100, "D42").Find(&products)//查询 `price > 100` 且 `code = "D42"` 的记录

3.修改数据

使用Model(&product)指定需要更新的模型(product 表示数据库中的记录)。

更新一条记录时,使用Update("Price", 200)来更新数据,第一个参数是字段名,第二个参数是要更新的值。
更新多条记录时,可以使用Struct更新,但使用Struct更新时,只会更新非零值,如果需要更新零值可以使用 Map 更新或使用Select 选择字段。
// Update - 将 product 的 price 更新为 200
db.Model(&product).Update("Price", value: 200)
// Update - 更新多个字段
db.Model(&product).Updates(Product{Price: 200,Code:"F42"})// 仅更新非零值字段
db.Model(&product).Updates(map[string]interface{}{"Price"200"Code""F42"})

product := Product{Code: "D42", Price: 0} // Price 为零值 
db.Model(&product).Select("Price").Updates(product)

另外使用 Table 方法可以直接指定表名进行数据更新,而不需要依赖模型结构体。这种方式常用于动态表名或者在没有定义模型结构体时操作数据库。

//如果没有 `Where`条件的更新会影响表中的所有记录,因此应谨慎使用。
db.Table("product").Where("Code = ?", D42).Update("price", 200)

4.删除数据

使用Delete方法删除记录,指定要操作的模型&product,指定删除的记录主键值1

// Delete - 删除 product
db.Delete(&product, 1)//从数据库中删除主键值为 `1` 的记录。

同样地Delete方法也可以使用Where条件,但是如果模型没有主键,GORM 无法自动生成 WHERE 条件,可能导致全部记录被删除。

db.Where("code = ?", "F42").Delete(&Product{})
需要注意的是,GORM内有几条默认的约定:
1.GORM默认使用名为ID的字段,作为主键
2.使用结构体的蛇形负数作为表名,字段名的蛇形作为列名
3.使用CreatedAt、UpdatedAt字段作为表的创建时间、更新时间

总结:GORM 是一个强大且灵活的 ORM 库,能够简化与数据库的交互。通过 GORM,可以方便地进行增、查、改、删等操作,同时支持更复杂的查询、事务处理以及数据冲突的处理。GORM 的自动迁移和多样化的操作方法使得开发者可以专注于业务逻辑,而不必过多关注数据库操作的细节。掌握 GORM 的常用操作和特性,可以有效提升开发效率,并保证代码的可维护性和扩展性。