当前位置: 首页 > news >正文

05 MyBatis 架构设计、渐进式综合项目与专家题库

本文件把 MyBatis 知识整合为可落地的系统能力:数据访问层架构、主线项目演进、模块边界、事务边界、多数据源、代码规范、专家清单和完整面试题答案。

1. 五层能力模型

层级能力目标
入门能配置 MyBatis,写 Mapper XML,完成 CRUD
进阶能写动态 SQL、ResultMap、TypeHandler、分页、测试
高级能理解执行流程、缓存、插件、事务和性能优化
精通能治理 SQL、批处理、多环境、迁移、可观测性
专家能设计数据访问架构、多数据源、读写分离、分库分表边界

2. 数据访问层架构

推荐分层:

controller -> application service / service -> domain service -> repository / mapper -> database

MyBatis Mapper 不应承担业务规则,它只负责 SQL 和表映射。

3. Mapper 与 Repository

简单项目:

Service -> Mapper

复杂项目:

Service -> Repository -> Mapper

Repository 封装多个 Mapper、组装领域对象、隐藏数据库表结构。

@RepositorypublicclassCourseRepository{privatefinalCourseMappercourseMapper;privatefinalLessonMapperlessonMapper;publicCourseDetailfindDetail(LongcourseId){CourseDOcourse=courseMapper.selectById(courseId);List<LessonDO>lessons=lessonMapper.selectByCourseId(courseId);returnCourseDetailAssembler.toDomain(course,lessons);}}

4. DO、DTO、Domain 分离

UserCreateRequest -> CreateUserCommand -> User domain -> UserDO -> users table

不要让数据库对象直接穿透到接口响应:

// 不推荐publicUserDOgetUser(Longid){returnuserMapper.selectById(id);}

更好:

publicUserResponsegetUser(Longid){Useruser=userRepository.findById(id);returnUserResponse.from(user);}

5. 主线项目:Knowledge Hub

业务背景:

  • 用户注册和登录。
  • 课程管理。
  • 章节管理。
  • 学习进度。
  • 订单和支付记录。
  • 搜索和筛选。
  • 后台管理。
  • 报表统计。

技术目标:

  • 用 MyBatis 管理数据访问。
  • 动态 SQL 支持复杂查询。
  • ResultMap 支持聚合对象。
  • Service 管理事务。
  • 测试覆盖 Mapper。
  • 性能优化支持大数据量查询。
  • 架构支持未来多数据源和读写分离。

6. Stage 1:用户 CRUD

表:

createtableusers(idbigintgeneratedbydefaultasidentityprimarykey,usernamevarchar(64)notnullunique,emailvarchar(128)notnull,statusvarchar(32)notnull,created_attimestampnotnull);

Mapper:

publicinterfaceUserMapper{UserDOselectById(Longid);intinsert(UserDOuser);intupdateStatus(@Param("id")Longid,@Param("status")Stringstatus);}

训练点:

  • Mapper XML。
  • 参数绑定。
  • 自增主键。
  • 基础事务。

7. Stage 2:课程搜索

需求:

  • keyword。
  • level。
  • status。
  • createdAt 范围。
  • 游标分页。

Query:

publicrecordCourseSearchQuery(Stringkeyword,Stringlevel,Stringstatus,LonglastId,Integerlimit){}

训练点:

  • where
  • if
  • 动态分页。
  • 索引设计。

8. Stage 3:课程详情聚合

课程详情包含:

  • course。
  • lessons。
  • teacher。
  • statistics。

策略:

  • 单个详情页可使用 join + ResultMap。
  • 大对象图可分多次查询组装。
  • 列表页避免一对多 join 破坏分页。

9. Stage 4:学习进度事务

需求:

  • 标记章节完成。
  • 更新课程进度。
  • 写学习日志。

Service:

@TransactionalpublicvoidcompleteLesson(LonguserId,LonglessonId){progressMapper.upsertLessonProgress(userId,lessonId);progressMapper.recalculateCourseProgress(userId,lessonId);learningLogMapper.insert(userId,lessonId,"COMPLETE");}

训练点:

  • 事务边界。
  • 幂等更新。
  • 唯一索引。
  • 并发安全。

10. Stage 5:订单与库存

需求:

  • 创建订单。
  • 扣减库存。
  • 防超卖。
  • 写订单日志。

SQL:

updatecourse_stocksetstock=stock-#{quantity}wherecourse_id=#{courseId}andstock>=#{quantity}

如果影响行数为 0,说明库存不足。

训练点:

  • 乐观并发控制。
  • 事务。
  • 行锁。
  • 异常回滚。

11. Stage 6:报表统计

需求:

  • 每日新增用户。
  • 课程完成率。
  • 热门课程。

策略:

  • 小规模直接 SQL 聚合。
  • 中等规模加索引和预聚合表。
  • 大规模用数仓、OLAP 或搜索引擎。

MyBatis 不应承担所有分析型查询压力。

12. Stage 7:多数据源与读写分离

场景:

  • 主库写。
  • 从库读。
  • 报表库。
  • 租户库。

风险:

  • 主从延迟。
  • 事务一致性。
  • 数据源路由错误。
  • 跨库事务复杂。

专家实践:

  • 事务内强制主库。
  • 写后读走主库或等待同步。
  • 路由逻辑集中。
  • 业务层不直接拼数据源。

13. Stage 8:分库分表边界

MyBatis 本身不是分库分表框架。可结合:

  • ShardingSphere。
  • 数据库中间件。
  • 应用层路由。

分库分表前先确认:

  • 单表数据量是否真的成为瓶颈。
  • 索引和归档是否已优化。
  • 查询维度是否稳定。
  • 跨分片查询如何处理。
  • 分布式事务是否可避免。

14. SQL 规范

建议:

  • Mapper 方法名表达业务查询意图。
  • 禁止${}拼接用户输入。
  • 动态 SQL 不写复杂业务规则。
  • 查询必须明确列名,避免select *
  • 大列表必须分页。
  • 更新必须带明确 where。
  • 重要 SQL 必须有测试。
  • 慢 SQL 必须 explain。

15. 目录规范

src/main/java/com/example/knowledge/ ├── user/ │ ├── controller/ │ ├── service/ │ ├── domain/ │ ├── repository/ │ └── mapper/ ├── course/ ├── order/ └── shared/ src/main/resources/mapper/ ├── user/ ├── course/ └── order/

按业务模块组织,避免所有 Mapper 堆在一个目录。

16. 专家架构检查清单

数据访问:

  • Mapper 是否只负责 SQL?
  • Service 是否控制事务?
  • 是否避免 Controller 直接调 Mapper?
  • 是否有 Repository 隔离复杂组装?

SQL:

  • 是否有注入风险?
  • 是否有 N+1?
  • 是否分页?
  • 是否有索引?
  • 是否 explain?

事务:

  • 边界是否正确?
  • 是否有自调用失效?
  • 是否捕获异常导致不回滚?
  • 是否存在长事务?

性能:

  • 是否深分页?
  • 是否返回过多列?
  • 是否批处理过大?
  • 是否连接池配置合理?

工程:

  • Mapper 测试是否覆盖关键 SQL?
  • 数据库迁移是否版本化?
  • SQL 日志是否脱敏?
  • 慢 SQL 是否可观测?

17. MyBatis 反模式

  • Controller 直接调用 Mapper。
  • XML 中写复杂业务规则。
  • ${}拼接用户输入。
  • 所有查询都select *
  • 列表页使用嵌套 select。
  • 不写 Mapper 测试。
  • 生产库手工改表。
  • 大事务包住远程调用。
  • 分页不考虑深分页。
  • 二级缓存无失效策略。
  • Mapper 返回 Map 贯穿业务层。
  • 数据库对象直接暴露给 API。

18. 面试题完整答案

18.1 MyBatis 适合什么架构位置?

MyBatis 适合放在数据访问层,负责 SQL 执行和数据库表映射。它不应承担业务规则、事务编排或接口响应组装。复杂项目中可在 Mapper 外增加 Repository,隔离表结构和领域模型。

18.2 为什么 Controller 不应该直接调用 Mapper?

Controller 负责 HTTP 协议和入参出参,不应知道数据库访问细节。直接调用 Mapper 会让事务、业务规则、权限和数据组装散落在接口层,难以复用和测试。应由 Service 或 Application Service 组织业务流程。

18.3 Repository 和 Mapper 有什么区别?

Mapper 是 MyBatis 的 SQL 映射接口,通常对应表或 SQL。Repository 是领域层或应用层的数据访问抽象,可组合多个 Mapper,隐藏数据库表结构,返回领域对象。简单项目可省略 Repository,复杂项目建议引入。

18.4 MyBatis 项目如何避免 SQL 混乱?

建立 SQL 规范:按业务模块组织 Mapper,方法命名表达意图,动态 SQL 控制复杂度,重要 SQL 有测试,禁止不安全${},统一分页和排序白名单,慢 SQL 进入审查流程。

18.5 如何设计事务边界?

事务边界应围绕一个业务用例,例如创建订单、完成课程、退款。事务内只放必要数据库操作,避免远程调用和长时间计算。事务应放 Service 层,并明确回滚异常。

18.6 多数据源如何治理?

数据源路由应集中处理,业务代码不应到处手动选择数据源。事务内必须明确数据源,读写分离要处理主从延迟,写后读要走主库或有一致性策略。跨库事务应尽量通过业务设计避免。

18.7 分库分表前要考虑什么?

先确认瓶颈是否真的来自单库单表。要评估索引、归档、缓存、读写分离是否已足够。分片键要稳定,跨分片查询、分页、事务、唯一 ID、数据迁移和运维成本都必须提前设计。

18.8 如何判断一个 MyBatis 开发者达到专家水平?

不仅能写 CRUD,还能理解执行链路、动态 SQL、ResultMap、缓存、事务、插件、性能、安全和架构边界。专家能设计数据访问规范,定位慢 SQL,治理事务和多数据源,并为未来扩展留下迁移路径。

19. 终极知识点总表

基础:

  • SqlSessionFactory。
  • SqlSession。
  • Mapper。
  • Mapper XML。
  • #{}/${}
  • CRUD。

进阶:

  • Dynamic SQL。
  • ResultMap。
  • association。
  • collection。
  • TypeHandler。
  • Spring Boot Starter。
  • Transaction。

高级:

  • Executor。
  • MappedStatement。
  • BoundSql。
  • ParameterHandler。
  • ResultSetHandler。
  • Cache。
  • Plugin。

精通:

  • Batch。
  • Pagination。
  • Testcontainers。
  • Flyway。
  • SQL explain。
  • Connection Pool。
  • Observability。

专家:

  • Repository。
  • 多数据源。
  • 读写分离。
  • 分库分表。
  • 缓存一致性。
  • 数据访问治理。
  • SQL 安全审计。

20. 项目演进路线扩展

20.1 v1 单体 CRUD

能力:

  • 用户、课程、章节基础表。
  • Mapper XML CRUD。
  • Service 事务。
  • H2 本地测试。

重点不是功能多,而是建立规范。

20.2 v2 复杂查询

能力:

  • 课程搜索。
  • 多条件筛选。
  • 游标分页。
  • 课程卡片 DTO。
  • Mapper 测试覆盖动态 SQL。

20.3 v3 聚合详情

能力:

  • 课程详情。
  • 章节列表。
  • 讲师信息。
  • 学习统计。

架构选择:

  • 简单详情可 ResultMap join。
  • 复杂详情用 Repository 多次查询组装。

20.4 v4 事务用例

能力:

  • 报名课程。
  • 扣减库存。
  • 写学习进度。
  • 写审计日志。

重点:

  • 幂等。
  • 乐观锁。
  • 唯一约束。
  • 事务回滚。

20.5 v5 性能治理

能力:

  • 慢 SQL 日志。
  • explain 审查。
  • 索引优化。
  • N+1 消除。
  • 连接池监控。

20.6 v6 架构升级

能力:

  • Repository。
  • 多数据源。
  • 读写分离。
  • 缓存层。
  • 数据迁移。
  • ADR。

21. 数据访问层 ADR 示例

# ADR: 课程详情使用 Repository 组装而不是深层 ResultMap ## 背景 课程详情包含课程、章节、讲师、统计数据。单条 join SQL 行数膨胀,ResultMap 复杂。 ## 决策 使用 CourseRepository 分别调用 CourseMapper、LessonMapper、TeacherMapper、StatisticMapper,然后组装 CourseDetail。 ## 后果 优点:SQL 简单、可测试、易优化。 代价:需要额外组装代码,并注意批量查询避免 N+1。

22. 团队 SQL Review 清单

  • 是否使用#{}绑定业务值?
  • 是否存在${}?是否白名单?
  • 是否明确列名?
  • where 条件是否完整?
  • update/delete 是否可能全表?
  • 是否有合适索引?
  • 是否有深分页?
  • 是否有 N+1?
  • 是否返回过多数据?
  • 是否有 Mapper 测试?
  • 是否需要 explain?

23. 专家场景题

23.1 课程搜索越来越慢怎么办?

先看 SQL 日志和 explain,确认是否索引失效、like 前缀通配、排序 filesort、返回数据过多。短期可加索引、改游标分页、减少列。中期可预计算热字段。若搜索复杂度高,考虑 Elasticsearch/OpenSearch,而不是继续用 MyBatis 承担全文搜索。

23.2 学习进度并发更新如何保证正确?

使用唯一约束保证幂等,如(user_id, lesson_id)唯一。完成操作可 upsert。课程进度更新可基于数据库聚合重新计算,或使用乐观锁版本号。事务内保持更新顺序一致,避免死锁。

23.3 多租户如何设计?

简单场景可每张表加tenant_id并在所有查询中显式过滤。复杂场景可使用 schema/db 隔离。插件可做兜底,但不能替代 SQL 规范和测试。必须防止跨租户访问,服务端权限和数据条件都要校验。

24. 架构专家题补充答案

24.1 MyBatis 项目什么时候需要 Repository?

当单个业务查询需要组合多个 Mapper、隐藏表结构、返回领域对象、隔离 DO 和 Domain 时,需要 Repository。简单 CRUD 可直接 Service 调 Mapper,但复杂业务中 Repository 能降低 Service 对数据库结构的耦合。

24.2 MyBatis 能否用于领域驱动设计?

可以,但不要让 Mapper 直接成为领域模型的一部分。Mapper 属于基础设施层,Repository 负责把数据库对象转换为领域对象。领域层不应依赖 MyBatis API 或 XML。

24.3 如何让 MyBatis 系统可持续演进?

建立 SQL 规范、Mapper 测试、数据库迁移、性能监控、慢 SQL 审查、分层架构和 ADR。随着复杂度上升,引入 Repository、缓存层、多数据源治理和读写分离,但不要过早复杂化。

25. 终极专家检查清单

基础:

  • Mapper namespace 正确。
  • 参数命名清晰。
  • XML 被扫描。
  • #{}使用正确。

动态 SQL:

  • 空条件安全。
  • 空集合安全。
  • 排序白名单。
  • OGNL 简单。

映射:

  • ResultMap 有 id。
  • 列别名清晰。
  • 一对多分页安全。
  • TypeHandler 无副作用。

事务:

  • Service 控制边界。
  • 无自调用失效。
  • 异常回滚明确。
  • 无长事务。

性能:

  • SQL explain。
  • 索引匹配。
  • 无 N+1。
  • 无深分页。
  • 连接池合理。

安全:

  • 无 SQL 注入。
  • 日志脱敏。
  • 权限在服务端。
  • 多租户隔离。

架构:

  • DO/DTO/Domain 分离。
  • Mapper 不承载业务。
  • Repository 边界清晰。
  • 多数据源集中治理。
  • 数据迁移版本化。
http://www.jsqmd.com/news/758649/

相关文章:

  • 3分钟掌握BLiveChat:打造B站直播的YouTube风格弹幕系统
  • 如何在Web端实现低延迟FLV直播播放:flv.js完全实战指南
  • Taotoken用量看板与成本管理功能带来的预算控制体验
  • 微信语音转MP3终极指南:3分钟解锁silk-v3-decoder音频转换神器
  • 2026三亚旅拍婚纱照避坑指南|亲测10家靠谱机构,不踩雷不花冤枉钱 - charlieruizvin
  • m4s-converter终极指南:3分钟解锁B站缓存视频,跨设备自由播放
  • KMS智能激活脚本:Windows和Office免费永久激活的终极解决方案
  • 通过Taotoken管理控制台实现API Key的权限划分与访问审计
  • 【农业AI最后一公里攻坚】:Dify本地化部署必须攻克的6类政务内网限制与3套等保2.0合规方案
  • 终极Gofile下载指南:如何快速免费下载Gofile.io文件
  • 义乌写真首选|女人帮摄影,把温柔与高级焊在镜头里 - charlieruizvin
  • Dayflow:基于AI屏幕内容分析的智能时间追踪工具深度解析
  • 第四章《变化的艺术》 完整学习资料
  • 泉盛UV-K5/K6全功能固件:从基础对讲机到专业通信设备的蜕变之路
  • 如何让小爱音箱播放本地音乐?Xiaomusic 10分钟配置指南
  • m4s-converter:B站缓存视频转换与永久保存的完整解决方案
  • 3分钟快速安装APA第7版Word参考文献样式:终极免费解决方案
  • Mac微信插件:让你的微信体验提升10倍效率
  • 解锁Koikatu游戏潜力:HF Patch完整功能解析与实用指南
  • PyEcharts-Gallery:如何通过场景化模板解决Python数据可视化难题的完整指南
  • 深度学习与图神经网络在早期痴呆诊断中的应用
  • 《智能重生:从垃圾堆到AI工程师》——第五章 代码与灵魂
  • CoPaw:构建完全可控的个人AI工作站,实现多通道智能助手部署
  • Dify农业大模型微调部署实操:NVIDIA Jetson Orin+离线气象数据集,7天完成端到端田间验证
  • ComfyUI ControlNet Aux OpenPose预处理器参数缺失故障分析与修复指南
  • 2026年4月大连头部不锈钢抛丸六角棒厂家企业推荐,不锈钢抛丸方钢/不锈钢抛丸六角棒,不锈钢抛丸六角棒厂家品牌找哪家 - 品牌推荐师
  • AI生成图像检测:基于重建自由反演的新方法
  • 通过curl命令直接测试Taotoken聊天接口的快速方法
  • 200+网站通用小说下载器:一键保存全网小说,打造永久离线图书馆
  • 用Python搞定Kinect V2相机标定:从棋盘格拍摄到参数导出的保姆级避坑指南