GORM的基本使用 | 豆包MarsCode AI刷题

76 阅读3分钟

GORM的基本使用

Gorm model

定义一个映射数据库表的结构体,这类结构体称为model

type Orders struct {
    Id        uint      `gorm:"primary_key" json:"id"`
    GameId    uint      `json:"gameId"`
    ChannelId uint      `json:"channel_id"`
    CreatedBy string    `json:"createdBy"`
    CreatedAt time.Time `json:"createdAt"`
    UpdateBy  string    `json:"updateBy"`
    UpdateAt  time.Time `json:"updateAt"`
}

func (o Orders) TableName() string {
    return "Orders"
}

数据库连接

首先,分别安装 gorm 库本身以及 MySQL 数据库驱动

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

"github.com/jinzhu/gorm"也是一个受欢迎的开源的gorm库

gorm.io/gorm的使用大同小异

在代码中导入相关的包

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

进行数据库连接初始化,通过dsn字符串配置所需连接的数据库

调用 gorm.Open 方法完成数据库连接对象 db 的初始化

如果出现连接错误,则通过 panic 抛出异常信息

func main() {
    dsn := "root:12345678@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
       panic("db connect fail")
    }
}

数据库CRUD操作

创建操作(Create)

通过db.Create()进行插入数据,参数为一个model对象

批量插入则传入一个model对象slice

//插入
db.Create(&Orders{
    GameId:    1,
    ChannelId: 1,
})

//批量插入
ordersArr := []Orders{
    {GameId: 2, ChannelId: 2},
    {GameId: 3, ChannelId: 3},
    {GameId: 4, ChannelId: 4},
}

db.Create(&ordersArr)

查询操作(Read)

查询单条数据

通过db.First查询单条数据,第一个参数为查询对应的model对象

后续参数为查询条件

var orders Orders
db.First(&orders, 1)                   // 查找主键id为1的数据

db.First(&orders, "gameId = ?", 1)     // 查找gameId为1的数据

db.First(&orders, "channel_id = ?", 1) // 查找channel_id为1的数据

多条件查询

还可以通过db.Find查询数据,查询条件可以作为后续参数传入,或是通过db.Where指明查询条件

db.Order用来指明排序条件

var ordersResult []Orders

db.Find(&ordersResult, "gameId < ? AND channel_id < ?", 10, 10)

db.Where("gameId < ? AND channel_id < ?", 10, 10).Find(&ordersResult)

db.Where("gameId < ? AND channel_id < ?", 10, 10).Find(&ordersResult).Order("gameId Desc")

分页查询


var ordersResult []Orders

page := 2
pageSize := 10
offset := (page - 1) * pageSize

db.Offset(offset).Limit(pageSize).Find(&ordersResult)

更新操作(Update)

db.Model 用于指定所针对的model(也就是对应数据库中的表)

通过db.Modeldb.Updates配合使用完成更新,可以根据model对象map进行更新

当使用map进行更新时,我们可以更新零值

更新条件由db.Model中传递的对象中的值指定,或是通过db.Where指明更新条件(优先)

//UPDATE orders SET game_id = 10,channel_id = 10 WHERE id = 1;
db.Model(&Orders{Id: 1}).Updates(Orders{GameId: 10, ChannelId: 10})

//UPDATE orders SET game_id = 10,channel_id = 10 WHERE id = 1;
db.Model(&Orders{Id: 1}).Updates(map[string]interface{}{"gameId": 10, "channel_id": 10})

//UPDATE orders SET game_id = 20,channel_id = 20 WHERE id = 2;
db.Model(&Orders{Id: 1}).Updates(map[string]interface{}{"gameId": 20, "channel_id": 20}).Where(" id = ?", 2)

删除操作(Delete)

删除单个记录

通过db.Delete删除对应的数据

db.Delete(&Orders{Id: 1})

条件和批量删除

通过db.where进行条件批量地删除

db.Delete(&Orders{}).Where("gameId < ? " ,10)

软删除

软删除是说我们的数据不是真正从数据库中删除记录,而是标记记录已删除

type Orders struct {
    Id        uint      `gorm:"primary_key" json:"id"`
    GameId    uint      `json:"gameId"`
    ChannelId uint      `json:"channel_id"`
    CreatedBy string    `json:"createdBy"`
    CreatedAt time.Time `json:"createdAt"`
    UpdateBy  string    `json:"updateBy"`
    UpdateAt  time.Time `json:"updateAt"`
    DeletedAt   gorm.DeletedAt
}

通过添加 DeletedAt 字段实现,添加后与正常的删除操作一致,但是实现的是软删除

软删除后,记录仍然在数据库中,但通过常规查询不会被查到,除非使用db.Unscoped查询

var orders Orders

db.Unscoped().First(&orders, 1)

Gorm Hook

回调函数

是在CRUD前后自动调用的函数

一般使用场景: CRUD前设置CreatedByCreatedAtUpdateByUpdateAt字段的自动填充,减少代码工作量

CRUD后更新关联表的操作(更推荐在业务代码中实现)

type Orders struct {
    Id        uint      `gorm:"primary_key" json:"id"`
    GameId    uint      `json:"gameId"`
    ChannelId uint      `json:"channel_id"`
    CreatedBy string    `json:"createdBy"`
    CreatedAt time.Time `json:"createdAt"`
    UpdateBy  string    `json:"updateBy"`
    UpdateAt  time.Time `json:"updateAt"`
    Deleted   gorm.DeletedAt
}

func (receiver Orders) TableName() string {
    return "Orders"
}

func (o *Orders) BeforeCreate(tx *gorm.DB) error {
    // 实际中从请求上下文获取
    o.CreatedBy = "system"
    o.CreatedAt = time.Now()
    return nil
}

func (o *Orders) BeforeUpdate(tx *gorm.DB) error {
    o.UpdateBy = "system"
    o.UpdateAt = time.Now()
    return nil
}

// AfterCreate回调函数,用于在创建记录后输出表名和执行的SQL语句
func (o *Orders) AfterCreate(tx *gorm.DB) error {
    tableName := o.TableName()
    sql := tx.Dialector.Explain(tx.Statement.SQL.String(), tx.Statement.Vars...)
    log.Printf("数据库表名: %s, 完整sql: %s", tableName, sql)
    return nil
}