Gorm 模型

 

模型定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
type User struct {
gorm.Model
Birthday time.Time
Age int
Name string `gorm:"size:255"` // 默认长度为 255,可以自定义
Num int `gorm:"AUTO_INCREMENT"` // 自增长

CreditCard CreditCard
// 一对一关联关系 (has one - use CreditCard's UserID as foreign key)
Emails []Email
// 一对多关联关系 (has many - use Email's UserID as foreign key)

BillingAddress Address
// 一对一关联关系 (belongs to - use BillingAddressID as foreign key)
BillingAddressID sql.NullInt64 // 外键

ShippingAddress Address
// 一对一关联关系 (belongs to - use ShippingAddressID as foreign key)
ShippingAddressID int

IgnoreMe int `gorm:"-"` // 忽略这个字段
Languages []Language `gorm:"many2many:user_languages;"`
// 多对多关联关系, 'user_languages' is join table
}

type Email struct {
ID int
UserID int `gorm:"index"` // 外键,并创建索引
Email string `gorm:"type:varchar(100);unique_index"`
// `type` 是设置数据库类型的, `unique_index` 是创建唯一索引
Subscribed bool
}

type Address struct {
ID int
Address1 string `gorm:"not null;unique_index"`
// 字段不能为空,并且创建唯一索引
Address2 string `gorm:"type:varchar(100);unique_index"`
Post sql.NullString `gorm:"not null"`
}

type Language struct {
ID int
Name string `gorm:"index:idx_name_code"`
// 创建索引和定义索引名称,并且允许创建联合索引,在其他字段定义同样的索引名称,唯一索引也是同样操作
Code string `gorm:"index:idx_name_code"` // `unique_index` 也是同样
}

type CreditCard struct {
gorm.Model
UserID uint
Number string
}

模型约定

gorm.Model 结构体

gorm.Model 定义了四个字段,IDCreatedAtUpdatedAtDeletedAt,可以将结构体嵌入到自己定义的结构体中,或者在自己定义的结构体中定义自己需要的字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 模型的基本定义
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}

// 加入 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
type User struct {
gorm.Model
Name string
}

// 只定义 `ID`, `CreatedAt`
type User struct {
ID uint
CreatedAt time.Time
Name string
}

表名

表名是结构体名称的复数形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type User struct {} // default table name is `users`

// 自定义表名 `profiles`
func (User) TableName() string {
return "profiles"
}

// 根据判断选择表
func (u User) TableName() string {
if u.Role == "admin" {
return "admin_users"
} else {
return "users"
}
}

// 不使用复数形式设置表名
db.SingularTable(true)

配置默认的表名

使用 DefaultTableNameHandler 来处理表名,设置默认规则

1
2
3
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string  {
return "prefix_" + defaultTableName;
}

字段名称是 snake case 规则

字段名也能自定义

1
2
3
4
5
6
7
8
9
10
11
12
13
type User struct {
ID uint // 字段名是 `id`
Name string // 字段名是 `name`
Birthday time.Time // 字段名是 `birthday`
CreatedAt time.Time // 字段名是 `created_at`
}

// Overriding Column Name
type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // 设置字段名为 `beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"`
Age int64 `gorm:"column:age_of_the_beast"`
}

ID 默认是主键

1
2
3
4
5
6
7
8
9
10
11
type User struct {
ID uint // 字段 `ID` 默认是主键
Name string
}

// 也能自定义主键
type Animal struct {
AnimalId int64 `gorm:"primary_key"` // 设置 AnimalId 是主键
Name string
Age int64
}

CreatedAt 存储着记录的创建时间。
UpdatedAt 存储着记录的每次更新时间。
DeletedAt 存储着记录删除的时间,用于实现软删除的功能。

关联

Belongs To

belongs_to 关联创建两个模型之间一对一的关系。

屏幕快照 2017-12-10 下午9.23.46

1
2
3
4
5
6
7
8
9
10
11
// `User` belongs to `Profile`, `ProfileID` is the foreign key
type User struct {
gorm.Model
Profile Profile // belongs_to 声明形式
ProfileID int // belongs_to 声明形式,关联的外键ID
}

type Profile struct {
gorm.Model
Name string
}

指定外键(foreign key)

1
2
3
4
5
6
7
8
9
10
type Profile struct {
gorm.Model
Name string
}

type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileRefer"` // 使用 ProfileRefer 为外键
ProfileRefer uint
}

指定外键(foreign key)和关联键(association key)

1
2
3
4
5
6
7
8
9
10
11
type Profile struct {
gorm.Model
Refer int // 对应 User 表中的ID
Name string
}

type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileID;AssociationForeignKey:Refer"`
ProfileID int
}

Has One

has_one 关联也建立两个模型之间的一对一关系,但有所不同,这种关联表示模型拥有另一个模型。例如一个用户只有一个简述。

屏幕快照 2017-12-11 下午10.33.43

1
2
3
4
5
6
7
8
9
10
11
// User has one CreditCard, UserID 是外键
type User struct {
gorm.Model
CreditCard CreditCard
}

type CreditCard struct {
gorm.Model
UserID uint
Number string
}

指定外键

1
2
3
4
5
6
7
8
9
10
type Profile struct {
gorm.Model
Name string
UserRefer uint // 外键字段
}

type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:UserRefer"`
}

指定外键和关联键

1
2
3
4
5
6
7
8
9
10
11
type Profile struct {
gorm.Model
Name string
UserID uint
}

type User struct {
gorm.Model
Refer uint
Profile Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`
}

Has Many

has_many 关联是建立两个模型的一对多的关系。

屏幕快照 2017-12-11 下午10.31.31

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// User has many emails, UserID 是外键
type User struct {
gorm.Model
Emails []Email
}

type Email struct {
gorm.Model
Email string
UserID uint
}

db.Model(&user).Related(&emails)
//// SELECT * FROM emails WHERE user_id = 111; // 111 is user's primary key

ps. 一对多关联同样可以指定外键和关联键

Many To Many

many_to_many 关联是两个模型通过一张中间表建立多对多关系。

1
2
3
4
5
6
7
8
9
10
// User has and belongs to many languages, use `user_languages` as join table
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}

type Language struct {
gorm.Model
Name string
}

通过反推断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// User has and belongs to many languages, use `user_languages` as join table
// Make sure the two models are in different files
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}

type Language struct {
gorm.Model
Name string
Users []User `gorm:"many2many:user_languages;"`
}

db.Model(&language).Related(&users)
//// SELECT * FROM "users" INNER JOIN "user_languages" ON "user_languages"."user_id" = "users"."id" WHERE ("user_languages"."language_id" IN ('111'))

多态

has_many 和 has_one 支持多态,belongs_to 和 many_to_many 不支持多态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Cat struct {
Id int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Dog struct {
Id int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Toy struct {
Id int
Name string
OwnerId int
OwnerType string
}

 

原址

posted on 2020-06-19 02:33  ercom  阅读(291)  评论(0)    收藏  举报