目录
理解并记忆 GORM 的 Model 结构体可以通过以下几个步骤和技巧:
GORM Model定义(基于七米老师)
GORM 的 Model
是一个内嵌的结构体,它提供了一组通用的模型字段和方法,使得在定义你的数据模型时更加方便和一致。
GORM 的 Model
结构体通常定义如下:
type Model struct {
ID uint
CreatedAt time.Time `gorm:"column:create_at"`
UpdatedAt time.Time `gorm:"column:update_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at"`
}
ID
是一个自增的主键。CreatedAt
和UpdatedAt
是记录创建和更新时间的时间戳字段。DeletedAt
是一个用于软删除的字段(如果使用软删除功能)。
使用 Model
结构体的自定义数据模型
以下是如何在自定义数据模型中使用 Model
结构体(你可以将它嵌入到你自己的模型中)的示例:
package main
import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"log"
"time"
)
// Model 是 GORM 的基础模型,内嵌在其他模型中
type Model struct {
ID uint
CreatedAt time.Time `gorm:"column:create_at"`
UpdatedAt time.Time `gorm:"column:update_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at"`
}
// User 定义了一个用户模型,内嵌了 GORM 的 Model 结构体
type User struct {
Model // 内嵌 Model 以获得通用字段
Name string
Age int
Email string
}
func main() {
// 连接到 SQLite 数据库,实际使用中可能连接到 MySQL、PostgreSQL 等
dsn := "file:db.sqlite?mode=memory&cache=shared&_fk=1"
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
// 自动迁移数据库模式
db.AutoMigrate(&User{})
// 创建新用户
user := User{Name: "Alice", Age: 30, Email: "alice@example.com"}
db.Create(&user)
// 查询用户
var users []User
db.Find(&users)
log.Println(users)
// 更新用户信息
db.Model(&User{Name: "Alice"}).Updates(User{Age: 31})
// 删除用户
db.Delete(&User{Name: "Alice"}, &User{})
}
在这个示例中:
Model
结构体定义了一组通用字段,如ID
、CreatedAt
、UpdatedAt
和DeletedAt
。User
结构体内嵌了Model
,从而自动获得了这些通用字段。- 使用
AutoMigrate
方法自动创建数据库表,确保表结构与User
结构体一致。 - 使用
Create
方法添加新用户。 - 使用
Find
方法查询用户。 - 使用
Model
方法和Updates
来更新用户信息。 - 使用
Delete
方法删除用户。
这样,你就可以在你的应用程序中方便地使用 GORM 的 Model
结构体来简化数据库操作。
理解并记忆 GORM 的 Model
结构体可以通过以下几个步骤和技巧:
1. 理解基本概念
- ORM: 对象关系映射,允许你使用面向对象的方式来操作数据库。
- Model: GORM 中的
Model
是一个内嵌结构体,提供了数据库操作的通用字段和行为。
2. 熟悉基本字段
- ID: 主键,通常用于唯一标识数据库记录。
- CreatedAt: 创建时间,记录记录被创建的时间。
- UpdatedAt: 更新时间,记录记录最后被更新的时间。
- DeletedAt: 软删除时间,用于实现软删除功能。
3. 记忆技巧
- 首字母法: 记住字段的首字母,如
I
(ID),C
(CreatedAt),U
(UpdatedAt),D
(DeletedAt). - 关联记忆: 将字段与实际的数据库操作关联起来,比如
CreatedAt
与记录的创建时间关联。
4. 使用场景
- 定义模型: 在定义你的数据模型时,通常会内嵌
Model
结构体。 - 自动字段: 内嵌
Model
后,你的模型会自动获得ID
,CreatedAt
,UpdatedAt
等字段
结构体标记
使用结构体声明模型时,标记(tags)是可选项。gorm支持以下标记:
支持的结构体标记(Struct tags)
结构体标记(Tag) | 描述 |
---|---|
Column | 指定列名 |
Type | 指定列数据类型 |
Size | 指定列大小, 默认值255 |
PRIMARY_KEY | 将列指定为主键 |
UNIQUE | 将列指定为唯一 |
DEFAULT | 指定列默认值 |
PRECISION | 指定列精度 |
NOT NULL | 将列指定为非 NULL |
AUTO_INCREMENT | 指定列是否为自增类型 |
INDEX | 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引 |
UNIQUE_INDEX | 和 INDEX 类似,只不过创建的是唯一索引 |
EMBEDDED | 将结构设置为嵌入 |
EMBEDDED_PREFIX | 设置嵌入结构的前缀 |
- | 忽略此字段 |
关联相关标记(tags)
结构体标记(Tag) | 描述 |
---|---|
MANY2MANY | 指定连接表 |
FOREIGNKEY | 设置外键 |
ASSOCIATION_FOREIGNKEY | 设置关联外键 |
POLYMORPHIC | 指定多态类型 |
POLYMORPHIC_VALUE | 指定多态值 |
JOINTABLE_FOREIGNKEY | 指定连接表的外键 |
ASSOCIATION_JOINTABLE_FOREIGNKEY | 指定连接表的关联外键 |
SAVE_ASSOCIATIONS | 是否自动完成 save 的相关操作 |
ASSOCIATION_AUTOUPDATE | 是否自动完成 update 的相关操作 |
ASSOCIATION_AUTOCREATE | 是否自动完成 create 的相关操作 |
ASSOCIATION_SAVE_REFERENCE | 是否自动完成引用的 save 的相关操作 |
PRELOAD | 是否自动完成预加载的相关操作 |
GROM(默认行为)主键、表名的约定
主键(Primary Key)
GORM 默认会使用名为ID的字段作为表的主键。
type User struct {
ID string // 名为`ID`的字段会默认作为表的主键
Name string
}
// 使用`AnimalID`作为主键
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
表名(Table Name)
表名默认就是结构体名称的复数,例如:
package main
import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"log"
)
// User 定义了一个用户模型
type User struct {
gorm.Model
Name string
Age int
Email string
}
func main() {
// 连接到 SQLite 数据库
dsn := "file:db.sqlite?mode=memory&cache=shared&_fk=1"
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
// 自动迁移数据库模式
db.AutoMigrate(&User{})
// 创建新用户
user := User{Name: "Alice", Age: 30, Email: "alice@example.com"}
db.Create(&user)
// 查询用户
var users []User
db.Find(&users)
log.Println(users)
}
在这个例子中:
User
结构体定义了一个用户模型,内嵌了gorm.Model
以获得通用字段。- 表名默认为 "users",因为 GORM 将 "User" 自动转换为复数形式。
- 使用
AutoMigrate
方法自动创建数据库表,确保表结构与User
结构体一致。 - 使用
Create
方法添加新用户。 - 使用
Find
方法查询用户。
这样,你就可以看到 GORM 如何自动处理表名的生成。
禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user`
db.SingularTable(true)
也可以通过Table()
指定表名:
// 使用User结构体创建名为`deleted_users`的表
db.Table("deleted_users").CreateTable(&User{})
var deleted_users []User
db.Table("deleted_users").Find(&deleted_users)
SELECT * FROM deleted_users;
db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
DELETE FROM deleted_users WHERE name = 'jinzhu';
这段代码展示了 GORM 提供的灵活性,允许你通过 Table
方法指定表名,而不是依赖 GORM 自动推断的表名。这对于需要使用特定表名或已经存在的表名与 GORM 模型名称不匹配的情况非常有用。
GORM还支持更改默认表名称规则:
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "prefix_" + defaultTableName;
}
这段代码是 GORM 的一个配置示例,用于自定义表名的生成规则。GORM 允许你通过设置 gorm.DefaultTableNameHandler
来改变表名的默认生成逻辑。下面是对代码的详细解释:
gorm.DefaultTableNameHandler
: 这是一个全局变量,它是一个函数,用于处理和生成表名。函数签名
func(db *gorm.DB, defaultTableName string) string
: 这个函数接收两个参数,第一个是*gorm.DB
类型的db
,表示当前的数据库连接实例;第二个是defaultTableName
字符串,表示 GORM 根据模型名称自动生成的默认表名。函数返回一个字符串,即自定义后的表名。return "prefix_" + defaultTableName
: 这个函数的实现非常简单,它将为所有自动生成的表名添加前缀"prefix_"
。例如,如果模型名称是User
,GORM 默认会生成表名为"users"
,使用这个函数后,表名将变为"prefix_users"
。
示例应用场景:
假设你有一个数据库,所有表都遵循特定的命名规范,比如都以 "app_"
作为前缀。你可以设置 gorm.DefaultTableNameHandler
来确保所有模型都遵循这个规范:
时间戳跟踪
CreatedAt
如果模型有 CreatedAt
字段,该字段的值将会是初次创建记录的时间。
db.Create(&user) // `CreatedAt`将会是当前时间
// 可以使用`Update`方法来改变`CreateAt`的值
db.Model(&user).Update("CreatedAt", time.Now())
UpdatedAt
如果模型有UpdatedAt
字段,该字段的值将会是每次更新记录的时间。
db.Save(&user) // `UpdatedAt`将会是当前时间
db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间
DeletedAt
如果模型有DeletedAt
字段,调用Delete
删除该记录时,将会设置DeletedAt
字段为当前时间,而不是直接将记录从数据库中删除。
期末放假自学Gin框架,希望我们可以一起学习!