# mybatis-learn **Repository Path**: zdyumath/mybatis-learn ## Basic Information - **Project Name**: mybatis-learn - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-16 - **Last Updated**: 2026-08-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyBatis 教学多模块项目 这是一个可运行、可测试、可逐步扩展的 MyBatis 教学项目。前 10 个 Spring Boot 模块组成第一阶段“常用开发路径”,11~14 深入 MyBatis Core,15~22 聚焦 MyBatis-Spring 与工程扩展;第四阶段包含三个可独立运行的完整项目实战和一个公共工程基座。React 前端通过 Vite 代理连接 22 个教学模块。 ## 模块一览 | 模块 | 端口 | 教学主题 | 核心接口 | | --- | ---: | --- | --- | | `module-01-basic-crud` | 8081 | XML CRUD | `/api/users` | | `module-02-dynamic-sql` | 8082 | 动态查询与更新 | `/api/products` | | `module-03-association` | 8083 | 一对多、一对一 | `/api/association/*` | | `module-04-resultmap` | 8084 | ResultMap | `/api/articles` | | `module-05-cache` | 8085 | 二级缓存与失效 | `/api/config` | | `module-06-plugin` | 8086 | SQL 执行耗时插件 | `/api/orders` | | `module-07-annotation` | 8087 | 注解 CRUD | `/api/books` | | `module-08-transaction` | 8088 | 转账事务与回滚 | `/api/tx/*` | | `module-09-pagination` | 8089 | `limit/offset` 分页 | `/api/news` | | `module-10-batch` | 8090 | 批量插入与更新 | `/api/logs/*` | | `module-11-configuration-typehandler` | 8091 | 全局配置与 TypeHandler | `/api/configuration/documents` | | `module-12-advanced-mapping` | 8092 | 嵌套查询与高级 ResultMap | `/api/advanced-mapping/*` | | `module-13-session-executor` | 8093 | SqlSession、Executor 与 Cursor | `/api/session/jobs/*` | | `module-14-advanced-statements` | 8094 | 高级动态 SQL、selectKey 与 CALLABLE | `/api/statements/*` | | `module-15-mybatis-spring` | 8095 | MyBatis-Spring、SqlSessionTemplate 与事务同步 | `/api/spring/records` | | `module-16-multi-datasource` | 8096 | 多数据源与 Mapper/SessionFactory 隔离 | `/api/multi-datasource/overview` | | `module-17-read-write-splitting` | 8097 | AbstractRoutingDataSource 读写路由 | `/api/read-write/items` | | `module-18-custom-plugin` | 8098 | 自定义 Executor 拦截器 | `/api/custom-plugin/*` | | `module-19-redis-cache` | 8099 | Redis cache-aside 与缓存失效 | `/api/redis/*` | | `module-20-pagehelper` | 8100 | PageHelper count 与分页 SQL | `/api/pagehelper/products` | | `module-21-test-transaction` | 8101 | 事务提交与回滚探针 | `/api/test-transaction/*` | | `module-22-monitoring-audit` | 8102 | Actuator、Micrometer 与 SQL 审计 | `/api/monitoring/*` | 模块共用本地教学 schema `mybatis_teach`,但使用互不冲突的表。每个模块都可以独立启动。 ## 详细教学文档 每个模块 README 现在同时承担“可运行说明”和“课堂课件”两种职责:先讲概念和本项目场景,再按真实代码追踪请求到 SQL,最后提供正向实验、反例、边界、测试、课后练习和官方参考。建议按 01~10、11~14、15~22 三个阶段递进阅读。 | 模块 | 教学文档 | | --- | --- | | 01 基础 CRUD | [module-01-basic-crud/README.md](module-01-basic-crud/README.md) | | 02 动态 SQL | [module-02-dynamic-sql/README.md](module-02-dynamic-sql/README.md) | | 03 关联映射 | [module-03-association/README.md](module-03-association/README.md) | | 04 ResultMap | [module-04-resultmap/README.md](module-04-resultmap/README.md) | | 05 缓存 | [module-05-cache/README.md](module-05-cache/README.md) | | 06 插件 | [module-06-plugin/README.md](module-06-plugin/README.md) | | 07 注解 Mapper | [module-07-annotation/README.md](module-07-annotation/README.md) | | 08 事务 | [module-08-transaction/README.md](module-08-transaction/README.md) | | 09 手工分页 | [module-09-pagination/README.md](module-09-pagination/README.md) | | 10 批量操作 | [module-10-batch/README.md](module-10-batch/README.md) | | 11 配置与 TypeHandler | [module-11-configuration-typehandler/README.md](module-11-configuration-typehandler/README.md) | | 12 高级映射 | [module-12-advanced-mapping/README.md](module-12-advanced-mapping/README.md) | | 13 SqlSession 与 Executor | [module-13-session-executor/README.md](module-13-session-executor/README.md) | | 14 高级 SQL | [module-14-advanced-statements/README.md](module-14-advanced-statements/README.md) | | 15 MyBatis-Spring | [module-15-mybatis-spring/README.md](module-15-mybatis-spring/README.md) | | 16 多数据源 | [module-16-multi-datasource/README.md](module-16-multi-datasource/README.md) | | 17 读写分离 | [module-17-read-write-splitting/README.md](module-17-read-write-splitting/README.md) | | 18 自定义插件 | [module-18-custom-plugin/README.md](module-18-custom-plugin/README.md) | | 19 Redis 缓存 | [module-19-redis-cache/README.md](module-19-redis-cache/README.md) | | 20 PageHelper | [module-20-pagehelper/README.md](module-20-pagehelper/README.md) | | 21 测试事务 | [module-21-test-transaction/README.md](module-21-test-transaction/README.md) | | 22 监控与 SQL 审计 | [module-22-monitoring-audit/README.md](module-22-monitoring-audit/README.md) | 每课都可以按“读 `init.sql` → 启动模块 → 调接口 → 读 Mapper/XML → 修改一个边界 → 跑测试”的顺序学习。官方链接放在各模块文档末尾,仓库只保留针对当前代码的解释,不复制官方文档全文。 ## 第四阶段:完整项目实战 前三阶段解决 MyBatis 单点能力和工程扩展问题,第四阶段把这些能力组合成真实业务系统。Step 0~Step 3 已作为独立项目落在 `projects/` 下,不加入现有 22 个模块的默认导航。完整设计、数据库模型、API、页面、部署、测试和执行计划见 [CAPSTONE_PROJECTS_DESIGN.md](CAPSTONE_PROJECTS_DESIGN.md)。 第四阶段按以下顺序推进: 1. Step 0:[公共工程基座](projects/capstone-template/README.md),验证认证授权、统一协议、Flyway、Compose、测试和运维能力。 2. Step 1:[客户经营 CRM](projects/crm-platform/README.md),练习线索转化、商机漏斗、跟进、缓存、导出和审计。 3. Step 2:[研发项目协作台](projects/project-management/README.md),练习项目、迭代、任务树、看板、评论、工时和成员负载。 4. Step 3:[订单与库存中心](projects/order-inventory/README.md),练习订单事务、并发库存、双数据源、Cursor 导出和报表。 三个项目独立使用自己的后端、前端、MySQL、Redis、迁移脚本和 Docker Compose;不把微服务、消息队列等基础设施作为首期前置条件。 启动根前端开发服务器后,访问 `http://localhost:3000/capstones` 可以查看三个项目的前端、Swagger、健康检查和 Compose 服务状态,并直接执行项目启动/停止。也可以访问 `http://localhost:3000/ops`,在统一运维页面管理教学模块、根教学数据库和完整项目。完整项目的停止操作只执行 Compose `stop`,不会删除数据卷;这些进程控制接口只在本机 Vite 开发服务器中提供。 完整项目启动按钮会先使用项目 Compose 的默认镜像;如果本机 Docker Registry Mirror 对 Docker Hub 返回镜像元数据或拉取错误,按钮会自动使用备用镜像重试一次。可以在项目 `.env` 中设置 `MYBATIS_DOCKER_IMAGE_MIRROR` 覆盖备用镜像前缀,例如 `m.daocloud.io/docker.io/library`。 ## 功能路线图与实验工作台 项目后续功能的优先级、范围、验收标准和安全边界见 [FEATURE_ROADMAP.md](FEATURE_ROADMAP.md)。当前已实现首版“实验工作台”: - 访问 `http://localhost:3000/lab`,先查看实验步骤、请求示例和预期结果,再编辑参数和学习笔记后运行自动断言。 - 执行调试标签记录最近 HTTP 请求的地址、参数、响应摘要和耗时;可选读取模块 22 的 SQL 审计事件。 - 进度与错误标签记录实验通过次数、最近失败原因和各阶段完成情况,数据只保存在当前浏览器。 - 首页会显示实验总进度,失败实验不会修改数据库以外的本地学习记录;模块 21 的回滚探针除外,它专门验证写入后回滚。 启动前端后,每个模块页面都可以在“操作演示”和“教学文档”之间切换;文档视图直接读取上表中的 README。地址增加 `?view=docs` 后可以直达文档,例如 `http://localhost:3000/transaction?view=docs`。 ## 环境要求 - JDK 17+ - Maven 3.8+ - Node.js 20+ 与 npm - Docker Desktop(本地 MySQL 和 MySQL 集成测试需要) ## Docker 启动 默认 Compose 使用 MySQL 8.4 LTS,监听 `127.0.0.1:13306`。本地教学默认 root 密码是 `root`,不能用于生产。 ```powershell Copy-Item .env.mysql.example .env docker compose -f compose.mysql.yml up -d docker compose -f compose.mysql.yml ps ``` 首次创建数据卷时,MySQL 会按顺序执行全部 22 个幂等初始化脚本;Redis 使用独立的 `redis-data` 数据卷。不同 MySQL 大版本不能复用数据卷。镜像节点无法拉取 8.4 时,可在 `.env` 中临时设置: ```dotenv MYSQL_IMAGE=mysql:latest MYSQL_VOLUME_NAME=mybatis-teaching-mysql-latest-data ``` 按需构建并启动模块 01,而不同时启动所有后端: ```powershell docker compose -f compose.mysql.yml --profile backend up -d --build Invoke-RestMethod http://127.0.0.1:8081/api/users ``` 如果 Docker Hub 基础镜像也被本地代理限流,可通过 `MAVEN_BUILD_IMAGE` 和 `JAVA_RUNTIME_IMAGE` 临时指定可信镜像代理;标准镜像名仍是项目默认值。 停止服务不会删除数据卷: ```powershell docker compose -f compose.mysql.yml --profile backend down ``` ## 一键启动完整教学环境 需要逐页操作全部前端功能时,在项目根目录执行: ```powershell .\scripts\start-all.ps1 ``` 脚本会启动 Compose MySQL 和 Redis、重复执行 22 份幂等初始化脚本、构建端口缺失的 Maven 模块及其依赖、启动尚未监听的 `8081` 至 `8102` 后端,并启动前端。初始化脚本从仓库主机文件通过标准输入执行,因此已有旧 MySQL 容器即使没有新增 SQL 挂载也能升级初始化。它会实际请求每个模块的读取接口,全部返回成功后才报告就绪。已占用的端口保持不变,不会接管或停止对应进程;脚本自己启动的 PID 和日志保存在系统临时目录中。 访问 `http://localhost:3000`。停止脚本自己创建的进程、该项目的 Compose 后端和 MySQL(保留数据卷): ```powershell .\scripts\stop-all.ps1 ``` 调试后端时可保留 MySQL: ```powershell .\scripts\stop-all.ps1 -KeepMySql ``` `.env` 中的 `MYSQL_ROOT_PASSWORD`、`MYSQL_PORT` 和 `MYSQL_DATABASE` 会被脚本读取。也可用 `-MySqlPassword`、`-MySqlPort` 覆盖前两项。已有构建产物时可用 `-SkipBuild`;只启动数据库和后端时可用 `-SkipFrontend`。 ## 按模块启动与本地运维 可以只启动某个教学模块。单模块快捷脚本会启动或复用 MySQL、重复执行幂等初始化脚本,但不会启动第二个前端进程: ```powershell .\scripts\start-module.ps1 -Module module-02-dynamic-sql .\scripts\stop-module.ps1 -Module module-02-dynamic-sql ``` 也可以给全量脚本传入一个或多个模块名;不传 `-Modules` 时仍保持原来的全量行为: ```powershell .\scripts\start-all.ps1 -Modules module-02-dynamic-sql,module-08-transaction -SkipFrontend .\scripts\stop-all.ps1 -Modules module-02-dynamic-sql -KeepMySql ``` 只操作数据库时使用 `-DatabaseOnly`。启动数据库默认会执行初始化脚本,若只需要启动容器可加 `-SkipInit`;初始化脚本本身可以通过下面的命令重复执行: ```powershell .\scripts\start-all.ps1 -DatabaseOnly -SkipInit .\scripts\start-all.ps1 -DatabaseOnly .\scripts\stop-all.ps1 -DatabaseOnly ``` 运行前端开发服务器后,可访问 `http://localhost:3000/ops` 打开“本地运维”页面。页面会显示 MySQL healthy 状态、22 个后端端口的监听状态、脚本管理状态和 PID,并提供模块启停、数据库启停、初始化脚本重复执行,以及三个完整项目的 Compose 启停按钮。访问 `http://localhost:3000/capstones` 也可以在项目卡片内执行相同的完整项目操作。Redis 的启动随数据库启动脚本完成。运维 API 只在 Vite 开发服务器中注册,并且只接受本机 loopback 请求;生产构建不包含进程控制能力。 ## 本机启动模块 各模块默认连接 `localhost:3306`。连接 Compose MySQL 时,把模块 URL 改到 `13306`。例如: ```powershell $env:TRANSACTION_DB_URL='jdbc:mysql://127.0.0.1:13306/mybatis_teach?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC' mvn -pl module-08-transaction -am install -DskipTests mvn -f module-08-transaction/pom.xml spring-boot:run ``` 环境变量前缀依次为 `BASIC_CRUD`、`DYNAMIC_SQL`、`ASSOCIATION`、`RESULTMAP`、`CACHE`、`PLUGIN`、`ANNOTATION`、`TRANSACTION`、`PAGINATION`、`BATCH`、`CONFIGURATION`、`ADVANCED_MAPPING`、`SESSION_EXECUTOR`、`ADVANCED_STATEMENTS`、`MYBATIS_SPRING`、`MULTI_CUSTOMER`、`MULTI_REPORTING`、`RW_PRIMARY`、`RW_REPLICA`、`CUSTOM_PLUGIN`、`REDIS_CACHE`、`PAGEHELPER`、`TEST_TRANSACTION` 和 `MONITORING`;账号和密码后缀为 `_DB_USER`、`_DB_PWD`。 本地教学配置默认将每个模块的 Hikari 连接池上限设为 4、最小空闲连接设为 1,适合 22 个模块共享一个 MySQL;可通过 `MYBATIS_DATASOURCE_MAX_POOL_SIZE` 和 `MYBATIS_DATASOURCE_MIN_IDLE` 调整。 `default` 配置只面向本地教学。生产启动必须启用 `prod` profile,并显式传入 `SPRING_DATASOURCE_URL`、`SPRING_DATASOURCE_USERNAME`、`SPRING_DATASOURCE_PASSWORD`: ```powershell $env:SPRING_PROFILES_ACTIVE='prod' ``` ## 前端 ```powershell cd frontend npm ci npm run dev ``` 访问 `http://localhost:3000`。`/api/m01` 至 `/api/m22` 会分别代理到端口 `8081` 至 `8102`。 单独执行 `npm run dev` 只启动前端代理,不会启动任何后端。访问未启动模块时,Vite 会因为代理目标不可连接而返回 500;需要浏览全部页面时应先运行根目录的 `scripts/start-all.ps1`。 ## OpenAPI 模块 01、08、09、10、11、12、13、14 提供 OpenAPI JSON 与 Swagger UI。以模块 11 为例: - `http://localhost:8091/v3/api-docs` - `http://localhost:8091/swagger-ui/index.html` ## 验证 普通单元测试和前端质量检查不需要 Docker: ```powershell mvn clean test cd frontend npm run typecheck npm test npm run lint npm run build ``` 真实 MySQL 集成测试覆盖 01~14 模块的 Mapper/Core 行为、事务提交与回滚、批量 SQL、配置、TypeHandler、SqlSession、Executor 和 CALLABLE;第三阶段 15~22 另外通过真实 Docker MySQL/Redis 服务完成启动、读取和关键写入行为回归。全部 22 份初始化脚本也会在一键启动流程中重复执行: ```powershell $env:DOCKER_HOST='npipe:////./pipe/dockerDesktopLinuxEngine' $env:TESTCONTAINERS_RYUK_DISABLED='true' mvn -Pmysql-it verify "-Dmysql.it.image=mysql:latest" ``` Linux/macOS 通常不需要设置 `DOCKER_HOST`;能够正常运行 Ryuk 时也不应禁用它。CI 默认使用 MySQL 8.4。本机当前因镜像节点限流使用缓存的 `mysql:latest`(9.6)完成验证,仍保留 8.4 本机复测限制。 修复记录、完成定义和残余限制见 [PROJECT_REPAIR_PLAN.md](PROJECT_REPAIR_PLAN.md)。