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

高级查询技术专题

专题说明

本专题系统讲解 GORM 高级查询技术,涵盖子查询、联合查询(JOIN/UNION)、窗口函数、CTE(Common Table Expression)、JSON 字段查询、全文搜索及原生 SQL 执行等复杂场景,提升数据检索与处理能力。

学习目标

  1. 掌握子查询和嵌套查询在 GORM 中的实现方式
  2. 理解多表 JOIN 查询的构建与优化
  3. 学会使用窗口函数和 CTE 处理复杂聚合
  4. 掌握 JSON 字段查询和原生 SQL 执行方法

学习内容

本专题涵盖以下知识点:

  • 子查询与嵌套查询构建
  • 多表 JOIN 与 UNION 联合查询
  • 窗口函数(ROW_NUMBER/RANK 等)
  • CTE 递归与非递归查询
  • JSON 字段查询(MySQL 5.7+/PostgreSQL)
  • 原生 SQL 与 Raw 方法

学习建议

  1. 理解 SQL 执行计划,复杂查询前先用 EXPLAIN 分析
  2. 避免 N+1 查询问题,优先使用 JOIN 或 Preload
  3. 原生 SQL 适用于 GORM DSL 无法表达的复杂查询

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

📝 配套习题(19 题)

1
判断题

事务隔离级别越高(如 Serializable),数据库的并发性能就越低。

A

B

2
填空题

事务执行失败时,GORM 会返回错误。正确处理方式是检查 ______ 并决定是否需要______或返回给调用者。

3
单选题

GORM 是否支持跨多个数据库连接的事务?

A

支持,使用 db.Transaction 即可

B

不支持,需要使用分布式事务方案

C

支持,但需要使用 raw SQL

D

支持,但仅限相同类型的数据库

4
判断题

在嵌套事务中,如果内层事务返回 error 回滚到 SavePoint,外层事务仍然可以 Commit。

A

B

5
多选题

在 Web 应用中,如何将事务与中间件结合实现每个请求一个事务?

A

在中间件中开启事务,传给 handler

B

Handler 使用传入的事务对象执行操作

C

中间件根据 handler 返回的 error 决定 Commit 或 Rollback

D

每个 handler 自己开启和提交事务

6
单选题

GORM 中如何在创建记录前自动设置 UUID?

A

实现 BeforeCreate(tx *gorm.DB) error 方法

B

实现 BeforeSave(tx *gorm.DB) error 方法

C

使用 gorm.BeforeCreate tag

D

在 Create 方法中传入回调函数

7
多选题

以下哪些是 GORM 创建操作相关的钩子?

A

BeforeSave

B

BeforeCreate

C

AfterCreate

D

AfterSave

8
判断题

如果 BeforeCreate 钩子返回 error,GORM 会取消创建操作并返回该错误。

A

B

9
单选题

BeforeUpdate 和 BeforeSave 的主要区别是什么?

A

BeforeUpdate 只在更新时触发,BeforeSave 在创建和更新时都触发

B

BeforeUpdate 在 BeforeSave 之后触发

C

BeforeUpdate 不能返回 error

D

两者完全相同

10
多选题

在 BeforeUpdate 钩子中,如何获取被更新的字段?

A

使用 tx.Statement.Dest 获取目标对象

B

使用 tx.Statement.SelectAttrs 获取被更新的字段

C

直接使用模型对象(u.Name)获取旧值

D

使用钩子参数中的旧值对象

11
多选题

db.Model(&User{}).Select("id, name").Where("age > ?", 18).Order("name").Limit(10) 的 SQL 等价语句是?

A

SELECT id, name FROM users WHERE age > 18 ORDER BY name LIMIT 10

B

SELECT * FROM users WHERE age > 18 ORDER BY name LIMIT 10

C

SELECT id, name FROM users ORDER BY name LIMIT 10

D

查询顺序不影响最终 SQL

12
判断题

GORM 的链式查询是延迟执行的,只有在调用 Find/First/Take 等方法时才真正发送 SQL。

A

B

13
单选题

如何按部门统计用户数量?

A

db.Model(&User{}).Group("department").Count(&count)

B

db.Select("department, COUNT(*) as total").Group("department").Find(&results)

C

db.Group("department").Find(&users)

D

db.Model(&User{}).GroupBy("department")

14
多选题

以下哪些是 Having 方法的正确使用方式?

A

db.Select("department, COUNT(*) as cnt").Group("department").Having("cnt > ?", 5).Find(&results)

B

db.Group("department").Having("COUNT(*) > 5").Find(&results)

C

Having 必须在 Group 之后

D

db.Having("COUNT(*) > 5").Group("department").Find(&results)

15
单选题

实现第 3 页、每页 10 条的分页查询,应该使用什么参数?

A

db.Limit(10).Offset(20)

B

db.Limit(10).Offset(30)

C

db.Limit(3).Offset(10)

D

db.Limit(20).Offset(10)

16
多选题

如何在分页查询时获取总记录数?

A

先 db.Model(&User{}).Where(...).Count(&total),再分页查询

B

在分页查询的同一语句中返回总数

C

使用 db.Find(&users, db.Page(page, pageSize))

D

使用两次查询:一次 Count 一次 Find

17
填空题

分页查询中,Offset 的计算公式为 _________________,其中 page 从______开始。

18
单选题

如何执行原生 SQL 查询并扫描到结构体?

A

db.Raw("SELECT * FROM users WHERE age > ?", 18).Find(&users)

B

db.Raw("SELECT * FROM users WHERE age > ?", 18).Scan(&users)

C

db.Exec("SELECT * FROM users WHERE age > ?", 18)

D

A 和 B 都可以

19
判断题

db.Exec 适合执行 INSERT/UPDATE/DELETE 等修改操作,返回结果包含 RowsAffected。

A

B

← 上一个专题 高级并发与锁机制专题

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

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

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

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