这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
GORM 快速入门
安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
快速入门
这里使用mysql举例。首先我们需要新建一个数据库,例如db1
在Go语言中输入以下代码
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type Userinfo struct {
Id uint
Name string
Gender string
Hobby string
}
func main() {
// 连接数据库
dsn := "root:123456@tcp(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
//自动迁移
db.AutoMigrate(&Userinfo{})
u1 := Userinfo{Id: 1, Name: "张三", Gender: "男", Hobby: "学习"}
db.Create(&u1) //创建
}
以上代码执行结果如下
GORM 声明模型
模型定义
模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成
例如:
type User struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivatedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
约定
GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间
遵循 GORM 已有的约定,可以减少您的配置和代码量。如果约定不符合您的需求,GORM 允许您自定义配置它们
gorm.Model
GORM 定义一个 gorm.Model 结构体,其包括字段 ID、CreatedAt、UpdatedAt、DeletedAt
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
你可以将它嵌入到你的结构体中,以包含这几个字段
嵌入结构体
对于匿名字段,GORM 会将其字段包含在父结构体中,例如:
type User struct {
gorm.Model
Name string
}
// 等效于
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
对于正常的结构体字段,你也可以通过标签 embedded 将其嵌入,例如:
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Author Author `gorm:"embedded"`
Upvotes int32
}
// 等效于
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}
并且,您可以使用标签 embeddedPrefix 来为 db 中的字段名添加前缀,例如:
type Blog struct {
ID int
Author Author `gorm:"embedded;embeddedPrefix:author_"`
Upvotes int32
}
// 等效于
type Blog struct {
ID int64
AuthorName string
AuthorEmail string
Upvotes int32
}
GORM 创建
创建记录
user := User{Name: "张三", Age: 18, Birthday: time.Now()}
result := db.Create(&user) // 通过数据的指针来创建
user.ID // 返回插入数据的主键
result.Error // 返回 error
result.RowsAffected // 返回插入记录的条数
用指定的字段创建记录
创建记录并更新给出的字段
db.Select("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775")
创建一个记录且一同忽略传递给略去的字段值
db.Omit("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`birthday`,`updated_at`) VALUES ("2020-01-01 00:00:00.000", "2020-07-04 11:05:21.775")
GORM 删除
删除一条记录
删除一条记录时,删除对象需要指定主键,否则会触发批量Delete,例如:
// Email 的 ID 是 `10`
db.Delete(&email)
// DELETE from emails where id = 10;
// 带额外条件的删除
db.Where("name = ?", "张三").Delete(&email)
// DELETE from emails where id = 10 AND name = "张三";
根据主键删除
GORM允许通过主键(可以是复合主键)和内联条件来删除对象,它可以使用数字,如以下例子
db.Delete(&User{}, 10)
// DELETE FROM users WHERE id = 10;
db.Delete(&User{}, "10")
// DELETE FROM users WHERE id = 10;
db.Delete(&users, []int{1,2,3})
// DELETE FROM users WHERE id IN (1,2,3);
批量删除
如果指定的值不包括主属性,那么 GORM 会执行批量删除,它将删除所有匹配的记录
db.Where("email LIKE ?", "%张三%").Delete(&Email{})
// DELETE from emails where email LIKE "%张三%";
db.Delete(&Email{}, "email LIKE ?", "%张三%")
// DELETE from emails where email LIKE "%张三%";
软删除
如果你的模型包含了一个gorm.deletedat字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力!拥有软删除能力的模型调用Delete时,记录不会被数据库删除。但GORM会将DeletedAt置为当前时间, 并且你不能再通过普通的查询方法找到该记录。
// user 的 ID 是 `111`
db.Delete(&user)
// UPDATE users SET deleted_at="2022-03-04 10:16" WHERE id = 111;
// 批量删除
db.Where("age = ?", 20).Delete(&User{})
// UPDATE users SET deleted_at="2022-03-04 10:16" WHERE age = 20;
// 在查询时会忽略被软删除的记录
db.Where("age = 20").Find(&user)
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
如果你不想引入gorm.Model,你也可以这样启用软删除特性
type User struct {
ID int
Deleted gorm.DeletedAt
Name string
}