Gorm 入门 | 青训营笔记

103 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

Gorm

Gorm 是一个迭代了10年的 ORM 的框架,拥有丰富的扩展

官方文档

数据库支持

  • 目前支持 MySQL、SQLServer、PostgreSQL、SQLite
  • 通过驱动连接数据库(类似 Spring),如果需要连接其他类型的数据库,可以复用/自行开发驱动
import (
    "gorm.io/driver/sqlserver"
    "gorm.io/gorm"
)
//dsn: Data Source Name
dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})

基本使用

image.png

约定

  • 使用名为 ID 的字段作为主键

  • 使用结构体的 “蛇形负数“ 作为表名

  • 字段的蛇形作为列名

  • 使用 CreateAt、UpdateAt 字段作为创建、更新时间

Gorm 创建数据

image.png

使用 Upsert

使用 clause.OnConflict 处理数据冲突

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

通过 default 标签为字段定义默认值

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

Gorm 查询数据

image.png

First 的使用踩坑
  • 使用 First 时,需要注意查询不到的数据会返回 ErrRecordNotFound

  • 使用 Find 查询多条数据,查询不到数据不会返回错误

使用结构体作为查询条件

当使用结构体作为查询条件时,GORM 只会查询非零值字段。

这意味着如果字段值为 0, ", false 或其他零值,该字段不会被用于构建查询条件,此时应该使用 Map 构建查询条件

Gorm 更新数据

image.png

使用 Struct 更新时,只会更新非零值,与查询时同理,可以使用 Map 更新数据,或者使用 Select 选择字段

Gorm 删除数据

物理删除

image.png

这种删除会将数据从数据库中抹除

软删除

image.png

GORM 提供了 gorm.DeletedAt 方法用于帮助用户实现软删除

拥有软删除能力的 Model 调用 Delete 时,记录不会被从数据库中抹除,而是会将 DeletedAt 置为当前时间,并且不能通过正常的查询方法找到该记录

可以使用 Unscoped 查询到被软删除的数据

一般情况下使用软删

Gorm 事务

Gorm 提供了 Begin, Commit, Rollback 方法用于处理事务

image.png

注意:开始事务后,就不是使用 db 而是 tx 了

Gorm 还提供了 Transaction 方法避免用户漏写 Commit 和 Rollback

image.png

推荐使用 Transaction 方法

Gorm 链式调用

GORM 允许链式调用,所以可以将多条字句写在一起

例如

db.Where("name = ?", "Lily").Where("age = ?", 18).First(&user)

链式方法是将 Clauses 修改或添加到当前 Statement 的方法,例如:

Where, Select, Omit, Joins, Scopes, Preload, Raw (Raw can’t be used with other chainable methods to build SQL)…

———————————————— 原文作者:Go 技术论坛文档:《GORM 中文文档(v2)》 转自链接:learnku.com/docs/gorm/v… 版权声明:翻译文档著作权归译者和 LearnKu 社区所有。转载请保留原文链接

Gorm Hook

Hook 是在创建、查询、更新、删除等操作之前、之后自动调用的函数

任何 Hook 返回错误,Gorm将停止后续的操作并回滚事务

Gorm 性能提高

  • 对于写操作,为了确保数据的完整性,Gorm 会将它们封装在事务内运行,但这会降低性能,可以使用 SkipDefaultTransaction 关闭默认事务

  • 使用 PrepareStmt 缓存预编译语句可以提高后续调用的速度

Gorm 生态

工具地址
GORM 代码生成工具github.com/go-gorm/gen
GORM 分片库方案github.com/go-gorm/sha…
GORM 手动索引github.com/go-gorm/hin…
GORM 乐观锁github.com/go-gorm/opt…
GORM 读写分离github.com/go-gorm/dbr…
GORM OpenTelemetry 拓展github.com/go-gorm/ope…