全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📝 1 篇文章 20 道配套习题

关联关系管理专题

专题说明

本专题系统讲解 GORM 关联关系管理,包括一对一(BelongsTo/HasOne)、一对多(HasMany)、多对多(ManyToMany)关联的定义方式、Preload 预加载、Joins 关联查询、级联创建与删除,以及避免 N+1 查询的最佳实践。

学习目标

  1. 掌握四种关联关系(BelongsTo/HasOne/HasMany/ManyToMany)的定义方式
  2. 理解 Preload 预加载与 Joins 关联查询的区别和使用场景
  3. 学会级联创建、更新和删除操作
  4. 掌握关联查询优化方法,避免 N+1 问题

学习内容

本专题涵盖以下知识点:

  • BelongsTo / HasOne 一对一关联
  • HasMany 一对多关联
  • ManyToMany 多对多关联与连接表
  • Preload 预加载与 Nested Preload
  • Joins 关联查询
  • 级联操作与关联约束

学习建议

  1. 理解 BelongsTo 和 HasOne 的区别:外键在哪张表上
  2. 预加载数据量大时优先使用 Joins 减少查询次数
  3. 级联删除注意外键约束与 GORM 软删除的交互

📝 发现内容有误?点击此处直接编辑

📝 配套习题(20 题)

1
单选题

在 GORM 中,如何配置一对多关系?

A

使用 hasMany tag

B

在"一"方定义切片类型的字段

C

在"多"方定义切片类型的字段

D

使用 oneToMany tag

2
多选题

以下关于 GORM 一对多关系外键配置的描述,哪些是正确的?

A

默认使用"父级名+ID"作为外键(如 UserID)

B

可以使用 foreignKey tag 自定义外键

C

外键必须手动在数据库中创建

D

AutoMigrate 会自动创建外键约束

3
判断题

在 GORM 中查询一对多关系时,默认会自动加载关联的子记录。

A

B

4
单选题

在 GORM 中,如何配置多对多关系?

A

使用 hasMany tag

B

使用 many2many tag 指定中间表名

C

使用 belongsToMany tag

D

使用 joinTable tag

5
多选题

GORM 自动创建的多对多中间表包含哪些字段?

A

两个外键(分别指向两个表的主键)

B

中间表的主键

C

额外的自定义字段

D

两个表的时间戳

6
填空题

如果需要在多对多关系的中间表中添加额外字段(如创建时间),可以定义________________并使用 gorm:"many2many:中间表名;foreignKey:!!2_外键1;joinForeignKey:连接外键" 配置。

7
单选题

GORM 中 hasOne 和 belongsTo 的主要区别是什么?

A

hasOne 在拥有外键的表中配置,belongsTo 在被引用表中配置

B

hasOne 在被引用表中配置,belongsTo 在拥有外键的表中配置

C

hasOne 用于一对一,belongsTo 用于一对多

D

两者完全相同,只是命名不同

8
多选题

以下哪些是 GORM 一对一关系的正确配置方式?

A

使用 hasOne tag 在主表中配置

B

使用 belongsTo tag 在从表中配置

C

外键默认在主表 ID 字段

D

可以使用 foreignKey tag 自定义外键

9
单选题

在 GORM 中,如何预加载用户的订单数据?

A

db.Preload("Orders").Find(&users)

B

db.Load("Orders").Find(&users)

C

db.Include("Orders").Find(&users)

D

db.With("Orders").Find(&users)

10
多选题

以下关于 GORM Preload 条件过滤的描述,哪些是正确的?

A

db.Preload("Orders", "state = ?", "paid").Find(&users) 可以过滤订单

B

Preload 的条件只影响关联数据的查询,不影响主查询

C

db.Preload("Orders").Where("state = ?", "paid").Find(&users) 会同时过滤用户和订单

D

可以在 Preload 中使用 Order 和 Limit

11
判断题

GORM 的 Joins 方法使用 LEFT JOIN 一次性查询关联数据,比 Preload 更高效。

A

B

12
填空题

预加载用户的订单以及订单的商品,可以使用 db.Preload("Orders").Preload("____________").Find(&users)db.Preload("Orders.Items").Find(&______)

13
单选题

如何为 Preload 自定义查询条件?

A

db.Preload("Orders", func(db *gorm.DB) *gorm.DB { return db.Where("amount > ?", 100) }).Find(&users)

B

db.Preload("Orders").Where("amount > ?", 100).Find(&users)

C

db.Preload("Orders").Query("amount > ?", 100).Find(&users)

D

db.Preload("Orders", "amount > ?", 100).Find(&users)

14
多选题

以下哪些方法可以处理预加载关联不存在的情况?

A

Preload 默认不会报错,关联字段会是空切片或 nil

B

使用 Preload 的 error handler 处理未找到关联的错误

C

使用 Session 配置预加载失败时的行为

D

在 Preload 后检查关联字段是否为空

15
单选题

使用 Joins 查询用户及其订单,正确的写法是?

A

db.Joins("Orders").Find(&users)

B

db.Joins("JOIN orders ON orders.user_id = users.id").Find(&users)

C

db.Join("orders").Find(&users)

D

db.InnerJoin("orders").Find(&users)

16
多选题

以下关于 GORM 预加载 N+1 问题的描述,哪些是正确的?

A

Preload 通过两条 SQL 解决 N+1 问题(先查主表,再 IN 查关联表)

B

Joins 通过一条 JOIN SQL 解决 N+1 问题

C

不使用 Preload 或 Joins,循环中查询关联会产生 N+1 问题

D

GORM 的 AutoPreload 插件可以自动预加载所有关联

17
判断题

当预加载一对多关系的数据量很大时,可以使用 Preload 的 Limit 方法限制加载数量。

A

B

18
填空题

查询用户及其订单数量,可以使用 db.Preload("Orders").______("users.*, (SELECT count(*) FROM orders WHERE orders.user_id = users.id) as order_count").______(&users)

19
单选题

User hasOne Profile 关系中,外键默认在哪个表中?

A

users 表

B

profiles 表

C

中间表

D

两个表都有

20
多选题

以下关于 belongsTo 的描述哪些是正确的?

A

belongsTo 在拥有外键的模型中配置

B

belongsTo 表示"属于"另一个模型

C

外键可以在 belongsTo 中自定义

D

belongsTo 和 hasOne 可以互换使用

← 上一个专题 事务处理专题
下一个专题 → 分库分表与多租户专题

📝 发现内容有误?点击此处直接编辑

想查看更多习题和详细解析?
小程序提供完整的题库和详细解析

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库