CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
GraphQL 入门/课时/N+1 与 DataLoader
RawBlame
课时目录12 节

GraphQL 入门

  1. 01GraphQL 是什么
  2. 02Schema 与类型
  3. 03Query 与字段选择
  4. 04Mutation
  5. 05Resolver 模型
  6. 06Spring for GraphQL
  7. 07N+1 与 DataLoader
  8. 08Apollo Client
  9. 09GraphQL vs REST 选型
  10. 10GraphiQL 与 introspection
  11. 11安全与限流
  12. 12综合练习

N+1 与 DataLoader

批量加载、性能直觉。

30 分钟

N+1 与 DataLoader

GraphQL 字段级 Resolver 易导致 N+1 查询:列表含 N 条 track,每条解析 lessons 时各打一次 SQL。REST 列表接口常用 JOIN 一次取回;GraphQL 需 批量加载 意识。

学习目标

  • 识别 N+1 场景与日志特征
  • 理解 DataLoader 批处理与缓存语义
  • 知道何时 REST 一次 JOIN 更简单

核心内容

问题演示

Query:

query {
  tracks { slug lessons { title } }
}

朴素实现:

@SchemaMapping
public List<Lesson> lessons(Track track) {
    // 每个 track 一次 SELECT → 1 + N 次查询
    return lessonRepo.findByTrackSlug(track.getSlug());
}

假设 20 个 track → 21 次数据库往返。MySQL 主库 cf_lesson 在 spring-boot-essentials JPA 层同样受影响。

DataLoader 思路

@Bean
public BatchLoader<String, List<Lesson>> lessonsByTrackSlugLoader(LessonRepository repo) {
    return slugs -> CompletableFuture.supplyAsync(() -> {
        Map<String, List<Lesson>> grouped = repo.findByTrackSlugIn(slugs)
            .stream()
            .collect(Collectors.groupingBy(Lesson::getTrackSlug));
        return slugs.stream().map(s -> grouped.getOrDefault(s, List.of())).toList();
    });
}

同一请求 tick 内,多个 lessons Resolver 注册 key,框架 合并为一次 WHERE track_slug IN (...)。

REST 对照

GET /tracks?include=lessons 可在 Service 层一次 JOIN 或两次查询批量填充——CodeRoadMap 当前 REST 未内嵌 lessons,课时走独立 URL,换用 GraphQL 时必须主动优化,否则性能反劣于简单 REST。

MongoDB 场景

mongodb-essentials 嵌套文档可减少 JOIN,但 $lookup 聚合仍有成本;DataLoader 对 跨 collection 批量同样适用。

练习

  • 开启 SQL 日志,执行含 10+ track 的嵌套 Query,数 SELECT 次数
  • 设计 findByTrackSlugIn Repository 方法签名
  • 写一句话:为何 GraphQL「灵活」不等于「更快」

小结

N+1 是 GraphQL 必修课;DataLoader 批处理是标准解。 下一课 Apollo Client 前端查询与缓存。

加载本节练习…
← 上一课Spring for GraphQL下一课 →Apollo Client