4.gorm基础新-单表模型和单表操作

表结构

在gorm中,使用结构体表示一张表

例如User表

通常情况下,我们会使用Model结尾表示它是表的结构体

type UserModel struct {
  ID        int64     `gorm:"primaryKey"` // 主键
  Name      string    `gorm:"not null;unique"` // 不能为空,且唯一 
  CreatedAt time.Time // 在创建记录时自动设置为当前时间
}

标签参考这个 https://gorm.io/zh_CN/docs/models.html#字段标签

自动生成表

package main

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

type UserModel struct {
  ID        int64     `gorm:"primaryKey"`      // 主键
  Name      string    `gorm:"not null;unique"` // 不能为空,且唯一
  CreatedAt time.Time // 在创建记录时自动设置为当前时间。
}

func main() {
  // 连接数据库
  db, err := gorm.Open(mysql.Open("root:root@tcp(127.0.0.1:3306)/gorm_new_db?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
  if err != nil {
    fmt.Println(err)
    return
  }
  
  err = db.AutoMigrate(&UserModel{})
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("生成表结构成功!")
}

生成表结构只会新增字段,不会删除字段和更新字段

单表操作

包括增删改查

插入数据

// InsertData 插入数据
func InsertData() {
  user := UserModel{Name: "张三"}
  err := DB.Create(&user).Error
  // 创建成功之后,数据会回填
  fmt.Println(user, err)
}

批量插入

// InsertData 插入数据
func InsertData() {
  var users = []UserModel{
    {
      Name: "王五",
    },
    {
      Name: "李四",
    },
  }
  err := DB.Create(&users).Error
  fmt.Println(users, err)
}

特别注意:Create函数接收的参数是结构体的指针或者是切片

插入数据的钩子

type UserModel struct {
  ID        int64     `gorm:"primaryKey"`      // 主键
  Name      string    `gorm:"not null;unique"` // 不能为空,且唯一
  CreatedAt time.Time // 在创建记录时自动设置为当前时间。
}

func (u *UserModel) BeforeCreate(tx *gorm.DB) error {
  fmt.Println("创建的钩子函数")
  u.Name = "枫枫"
  return nil
}

如果在插入的钩子函数中,返回错误,则数据不会被插入

查询数据

// 查全部
var users []UserModel
DB.Find(&users)
fmt.Println(users)

// 带条件查询
users = []UserModel{}
DB.Find(&users, "name = ?", "张三")
fmt.Println(users)

// 获取一条记录
var user UserModel
DB.Take(&user)
fmt.Println(user)

// 如果查不到则会报错
user = UserModel{}
err := DB.Take(&user, "id = ?", 100).Error
if err == gorm.ErrRecordNotFound {
  fmt.Println("不存在的记录")
}

// 如果不想出现错误
user = UserModel{}
err = DB.Limit(1).Find(&user, "id = ?", 100).Error
fmt.Println(err)

// 打印实际的sql
DB.Debug().Take(&user, "id = ?", 1)

更新

有很多方法,Save、Update、UpdateColumn、Updates

不同的方法有不同的区别,如下:

  1. Save,有主键记录就是更新,并且可以更新零值,否则就是创建
  2. Update,可以更新零值,必须要有条件
  3. UpdateColumn,可以更新零值,不会走更新的Hook
  4. Updates,如果是结构体,则更新非零值,map可以更新零值

save

// 创建
var user = UserModel{
  Name: "枫枫1",
}
DB.Save(&user)
fmt.Println(user)

// 更新
user = UserModel{
  ID:        9,
  Name:      "枫枫2",
  CreatedAt: time.Now(),
}
DB.Save(&user)
fmt.Println(user)

更新钩子

func (u *UserModel) BeforeUpdate(tx *gorm.DB) (err error) {
  fmt.Println("更新的钩子函数")
  return nil
}

Update和UpdateColumn

DB.Model(&UserModel{}).
  Where("id = ?", 1).
  Update("name", "张三")  // 走了更新钩子

DB.Model(&UserModel{}).
  Where("id = ?", 1).
  UpdateColumn("name", "张三")

Updates

var user = UserModel{ID: 1}

DB.Model(&user).Updates(UserModel{
  Name: "张三丰",
})

user = UserModel{ID: 2}
// 不会更新零值
DB.Model(&user).Updates(UserModel{
  Name: "",
})

user = UserModel{ID: 2}
// 会更新零值
DB.Model(&user).Updates(map[string]any{
  "name": "",
})

Expr

通常用于获取原字段的数据

例如年龄加一

DB.Model(&UserModel{}).
  Where("id = ?", 1).
  UpdateColumn("age", gorm.Expr("age + 1"))

删除

var user = UserModel{ID: 10}
DB.Delete(&user)

DB.Delete(&UserModel{}, 9)

// 批量删除
DB.Delete(&UserModel{}, []int{1, 2, 3})

钩子函数

func (u *UserModel) BeforeDelete(tx *gorm.DB) (err error) {
    fmt.Println("删除钩子")
    return
}

软删除

如果你的模型包含了 gorm.DeletedAt字段(该字段也被包含在gorm.Model中),那么该模型将会自动获得软删除的能力

当调用Delete时,GORM并不会从数据库中删除该记录,而是将该记录的DeleteAt设置为当前时间,而后的一般查询方法将无法查找到此条记录。

查找被删除的记录

DB.Unscoped().Find(&users)

永久删除

db.Unscoped().Delete(&user)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值