GORM-关系映射

1. 一对一关系

在一对一关系中,一个实体与另一个实体之间存在唯一映射关系。例如,一个用户对应一个地址。

定义模型

1
2
3
4
5
6
7
8
9
10
11
type User struct {
ID uint
Name string
Address Address `gorm:"foreignKey:UserID"`
}

type Address struct {
ID uint
UserID uint
Street string
}
  • foreignKey:指定外键字段。

插入数据

1
2
3
4
5
user := User{
Name: "Alice",
Address: Address{Street: "123 Main St"},
}
db.Create(&user)

查询数据

1
2
3
var user User
db.Preload("Address").First(&user)
fmt.Println(user.Address.Street)

2. 一对多关系

在一对多关系中,一个实体可以有多个相关实体。例如,一个用户可以有多篇文章。

定义模型

1
2
3
4
5
6
7
8
9
10
11
type User struct {
ID uint
Name string
Articles []Article `gorm:"foreignKey:UserID"`
}

type Article struct {
ID uint
UserID uint
Title string
}

插入数据

1
2
3
4
5
6
7
8
user := User{
Name: "Bob",
Articles: []Article{
{Title: "First Article"},
{Title: "Second Article"},
},
}
db.Create(&user)

查询数据

1
2
3
4
5
var user User
db.Preload("Articles").First(&user)
for _, article := range user.Articles {
fmt.Println(article.Title)
}

3. 多对多关系

在多对多关系中,一个实体可以与多个其他实体相关联。例如,学生和课程之间的关系。

定义模型

1
2
3
4
5
6
7
8
9
10
11
type Student struct {
ID uint
Name string
Classes []Class `gorm:"many2many:student_classes;"`
}

type Class struct {
ID uint
Name string
Students []Student `gorm:"many2many:student_classes;"`
}
  • many2many:指定连接表的名称。

插入数据

1
2
3
4
5
6
7
8
student := Student{
Name: "Charlie",
Classes: []Class{
{Name: "Math"},
{Name: "Science"},
},
}
db.Create(&student)

查询数据

1
2
3
4
5
var student Student
db.Preload("Classes").First(&student)
for _, class := range student.Classes {
fmt.Println(class.Name)
}

4. 总结

GORM 提供了丰富的关系映射功能:

  • 一对一:通过 foreignKey 定义外键字段,使用 Preload 查询关联数据。
  • 一对多:通过切片类型定义多条关联记录。
  • 多对多:通过 many2many 建立连接表,简化多对多关系的操作。