ai-engineering-init 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/code-reviewer.md +139 -0
- package/.claude/agents/project-manager.md +159 -0
- package/.claude/audio/completed.wav +0 -0
- package/.claude/commands/add-todo.md +255 -0
- package/.claude/commands/check.md +210 -0
- package/.claude/commands/crud.md +454 -0
- package/.claude/commands/dev.md +503 -0
- package/.claude/commands/init-docs.md +681 -0
- package/.claude/commands/next.md +251 -0
- package/.claude/commands/progress.md +242 -0
- package/.claude/commands/start.md +199 -0
- package/.claude/commands/sync.md +307 -0
- package/.claude/commands/update-status.md +428 -0
- package/.claude/docs/Mixin/344/275/277/347/224/250/346/214/207/345/215/227.md +299 -0
- package/.claude/docs/README.md +167 -0
- package/.claude/docs//345/211/215/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +599 -0
- package/.claude/docs//345/220/216/347/253/257/345/274/200/345/217/221/346/214/207/345/215/227.md +726 -0
- package/.claude/docs//345/267/245/344/275/234/346/265/201/345/274/200/345/217/221/346/214/207/345/215/227.md +714 -0
- package/.claude/docs//345/267/245/345/205/267/347/261/273/344/275/277/347/224/250/346/214/207/345/215/227.md +463 -0
- package/.claude/docs//346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/350/247/204/350/214/203.md +390 -0
- package/.claude/docs//346/226/260/345/212/237/350/203/275/345/274/200/345/217/221/346/265/201/347/250/213/350/247/204/350/214/203.md +688 -0
- package/.claude/docs//346/226/260/351/241/271/347/233/256/345/274/200/345/217/221/346/265/201/347/250/213.md +365 -0
- package/.claude/docs//346/241/206/346/236/266/350/257/264/346/230/216.md +393 -0
- package/.claude/docs//350/267/257/347/224/261/351/205/215/347/275/256/346/214/207/345/215/227.md +246 -0
- package/.claude/framework-config.json +73 -0
- package/.claude/hooks/pre-tool-use.js +117 -0
- package/.claude/hooks/skill-forced-eval.js +167 -0
- package/.claude/hooks/stop.js +58 -0
- package/.claude/settings.json +41 -0
- package/.claude/skills/add-skill/SKILL.md +352 -0
- package/.claude/skills/api-development/SKILL.md +560 -0
- package/.claude/skills/architecture-design/SKILL.md +756 -0
- package/.claude/skills/backend-annotations/SKILL.md +674 -0
- package/.claude/skills/banana-image/CHANGELOG.md +37 -0
- package/.claude/skills/banana-image/README.md +146 -0
- package/.claude/skills/banana-image/SKILL.md +164 -0
- package/.claude/skills/banana-image/assets/logo.png +0 -0
- package/.claude/skills/banana-image/references/advanced-usage.md +189 -0
- package/.claude/skills/banana-image/scripts/apply_template.py +125 -0
- package/.claude/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.claude/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.claude/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.claude/skills/banana-image/scripts/package.json +18 -0
- package/.claude/skills/banana-image/scripts/requirements.txt +10 -0
- package/.claude/skills/banana-image/templates/poster.json +22 -0
- package/.claude/skills/banana-image/templates/product.json +17 -0
- package/.claude/skills/banana-image/templates/social.json +22 -0
- package/.claude/skills/banana-image/templates/thumbnail.json +17 -0
- package/.claude/skills/brainstorm/SKILL.md +648 -0
- package/.claude/skills/bug-detective/SKILL.md +1206 -0
- package/.claude/skills/code-patterns/SKILL.md +590 -0
- package/.claude/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.claude/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.claude/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.claude/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.claude/skills/crud-development/SKILL.md +649 -0
- package/.claude/skills/data-permission/SKILL.md +599 -0
- package/.claude/skills/database-ops/SKILL.md +407 -0
- package/.claude/skills/error-handler/SKILL.md +371 -0
- package/.claude/skills/file-oss-management/SKILL.md +863 -0
- package/.claude/skills/git-workflow/SKILL.md +375 -0
- package/.claude/skills/json-serialization/SKILL.md +357 -0
- package/.claude/skills/leniu-api-development/SKILL.md +803 -0
- package/.claude/skills/leniu-architecture-design/SKILL.md +598 -0
- package/.claude/skills/leniu-backend-annotations/SKILL.md +664 -0
- package/.claude/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.claude/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.claude/skills/leniu-data-permission/SKILL.md +256 -0
- package/.claude/skills/leniu-database-ops/SKILL.md +426 -0
- package/.claude/skills/leniu-error-handler/SKILL.md +462 -0
- package/.claude/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.claude/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.claude/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.claude/skills/leniu-java-entity/SKILL.md +751 -0
- package/.claude/skills/leniu-java-export/SKILL.md +560 -0
- package/.claude/skills/leniu-java-logging/SKILL.md +832 -0
- package/.claude/skills/leniu-java-mq/SKILL.md +338 -0
- package/.claude/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.claude/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.claude/skills/leniu-java-task/SKILL.md +367 -0
- package/.claude/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.claude/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.claude/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.claude/skills/leniu-mealtime/SKILL.md +215 -0
- package/.claude/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.claude/skills/leniu-security-guard/SKILL.md +520 -0
- package/.claude/skills/leniu-utils-toolkit/SKILL.md +380 -0
- package/.claude/skills/openspec-apply-change/SKILL.md +156 -0
- package/.claude/skills/openspec-archive-change/SKILL.md +114 -0
- package/.claude/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.claude/skills/openspec-continue-change/SKILL.md +118 -0
- package/.claude/skills/openspec-explore/SKILL.md +290 -0
- package/.claude/skills/openspec-ff-change/SKILL.md +101 -0
- package/.claude/skills/openspec-new-change/SKILL.md +74 -0
- package/.claude/skills/openspec-onboard/SKILL.md +529 -0
- package/.claude/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.claude/skills/openspec-verify-change/SKILL.md +168 -0
- package/.claude/skills/performance-doctor/SKILL.md +627 -0
- package/.claude/skills/project-navigator/SKILL.md +305 -0
- package/.claude/skills/redis-cache/SKILL.md +839 -0
- package/.claude/skills/scheduled-jobs/SKILL.md +633 -0
- package/.claude/skills/security-guard/SKILL.md +748 -0
- package/.claude/skills/sms-mail/SKILL.md +766 -0
- package/.claude/skills/social-login/SKILL.md +668 -0
- package/.claude/skills/store-pc/SKILL.md +366 -0
- package/.claude/skills/task-tracker/SKILL.md +307 -0
- package/.claude/skills/tech-decision/SKILL.md +393 -0
- package/.claude/skills/tenant-management/SKILL.md +603 -0
- package/.claude/skills/test-development/SKILL.md +755 -0
- package/.claude/skills/ui-pc/SKILL.md +438 -0
- package/.claude/skills/utils-toolkit/SKILL.md +615 -0
- package/.claude/skills/websocket-sse/SKILL.md +716 -0
- package/.claude/skills/workflow-engine/SKILL.md +676 -0
- package/.claude/templates//345/276/205/345/212/236/346/270/205/345/215/225/346/250/241/346/235/277.md +56 -0
- package/.claude/templates//351/234/200/346/261/202/346/226/207/346/241/243/346/250/241/346/235/277.md +85 -0
- package/.claude/templates//351/241/271/347/233/256/347/212/266/346/200/201/346/250/241/346/235/277.md +43 -0
- package/.codex/skills/add-skill/SKILL.md +352 -0
- package/.codex/skills/add-todo/SKILL.md +269 -0
- package/.codex/skills/api-development/SKILL.md +693 -0
- package/.codex/skills/architecture-design/SKILL.md +628 -0
- package/.codex/skills/backend-annotations/SKILL.md +664 -0
- package/.codex/skills/banana-image/CHANGELOG.md +37 -0
- package/.codex/skills/banana-image/README.md +146 -0
- package/.codex/skills/banana-image/SKILL.md +164 -0
- package/.codex/skills/banana-image/assets/logo.png +0 -0
- package/.codex/skills/banana-image/references/advanced-usage.md +189 -0
- package/.codex/skills/banana-image/scripts/apply_template.py +125 -0
- package/.codex/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.codex/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.codex/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.codex/skills/banana-image/scripts/package.json +18 -0
- package/.codex/skills/banana-image/scripts/requirements.txt +10 -0
- package/.codex/skills/banana-image/templates/poster.json +22 -0
- package/.codex/skills/banana-image/templates/product.json +17 -0
- package/.codex/skills/banana-image/templates/social.json +22 -0
- package/.codex/skills/banana-image/templates/thumbnail.json +17 -0
- package/.codex/skills/brainstorm/SKILL.md +648 -0
- package/.codex/skills/bug-detective/SKILL.md +1206 -0
- package/.codex/skills/check/SKILL.md +367 -0
- package/.codex/skills/code-patterns/SKILL.md +442 -0
- package/.codex/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.codex/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.codex/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.codex/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.codex/skills/crud/SKILL.md +265 -0
- package/.codex/skills/crud-development/SKILL.md +637 -0
- package/.codex/skills/data-permission/SKILL.md +591 -0
- package/.codex/skills/database-ops/SKILL.md +553 -0
- package/.codex/skills/dev/SKILL.md +187 -0
- package/.codex/skills/error-handler/SKILL.md +361 -0
- package/.codex/skills/file-oss-management/SKILL.md +863 -0
- package/.codex/skills/git-workflow/SKILL.md +375 -0
- package/.codex/skills/init-docs/SKILL.md +194 -0
- package/.codex/skills/json-serialization/SKILL.md +357 -0
- package/.codex/skills/leniu-api-development/SKILL.md +803 -0
- package/.codex/skills/leniu-architecture-design/SKILL.md +594 -0
- package/.codex/skills/leniu-backend-annotations/SKILL.md +662 -0
- package/.codex/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.codex/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.codex/skills/leniu-data-permission/SKILL.md +256 -0
- package/.codex/skills/leniu-database-ops/SKILL.md +426 -0
- package/.codex/skills/leniu-error-handler/SKILL.md +462 -0
- package/.codex/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.codex/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.codex/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.codex/skills/leniu-java-entity/SKILL.md +751 -0
- package/.codex/skills/leniu-java-export/SKILL.md +560 -0
- package/.codex/skills/leniu-java-logging/SKILL.md +832 -0
- package/.codex/skills/leniu-java-mq/SKILL.md +338 -0
- package/.codex/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.codex/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.codex/skills/leniu-java-task/SKILL.md +367 -0
- package/.codex/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.codex/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.codex/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.codex/skills/leniu-mealtime/SKILL.md +215 -0
- package/.codex/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.codex/skills/leniu-security-guard/SKILL.md +520 -0
- package/.codex/skills/leniu-utils-toolkit/SKILL.md +378 -0
- package/.codex/skills/next/SKILL.md +137 -0
- package/.codex/skills/openspec-apply-change/SKILL.md +156 -0
- package/.codex/skills/openspec-archive-change/SKILL.md +114 -0
- package/.codex/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.codex/skills/openspec-continue-change/SKILL.md +118 -0
- package/.codex/skills/openspec-explore/SKILL.md +290 -0
- package/.codex/skills/openspec-ff-change/SKILL.md +101 -0
- package/.codex/skills/openspec-new-change/SKILL.md +74 -0
- package/.codex/skills/openspec-onboard/SKILL.md +529 -0
- package/.codex/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.codex/skills/openspec-verify-change/SKILL.md +168 -0
- package/.codex/skills/performance-doctor/SKILL.md +627 -0
- package/.codex/skills/progress/SKILL.md +193 -0
- package/.codex/skills/project-navigator/SKILL.md +286 -0
- package/.codex/skills/redis-cache/SKILL.md +829 -0
- package/.codex/skills/scheduled-jobs/SKILL.md +633 -0
- package/.codex/skills/security-guard/SKILL.md +739 -0
- package/.codex/skills/sms-mail/SKILL.md +766 -0
- package/.codex/skills/social-login/SKILL.md +668 -0
- package/.codex/skills/start/SKILL.md +154 -0
- package/.codex/skills/store-pc/SKILL.md +491 -0
- package/.codex/skills/sync/SKILL.md +149 -0
- package/.codex/skills/task-tracker/SKILL.md +307 -0
- package/.codex/skills/tech-decision/SKILL.md +393 -0
- package/.codex/skills/tenant-management/SKILL.md +603 -0
- package/.codex/skills/test-development/SKILL.md +755 -0
- package/.codex/skills/ui-pc/SKILL.md +475 -0
- package/.codex/skills/update-status/SKILL.md +159 -0
- package/.codex/skills/utils-toolkit/SKILL.md +593 -0
- package/.codex/skills/websocket-sse/SKILL.md +716 -0
- package/.codex/skills/workflow-engine/SKILL.md +676 -0
- package/.cursor/agents/code-reviewer.md +139 -0
- package/.cursor/agents/project-manager.md +159 -0
- package/.cursor/commands/opsx-apply.md +152 -0
- package/.cursor/commands/opsx-archive.md +157 -0
- package/.cursor/commands/opsx-bulk-archive.md +242 -0
- package/.cursor/commands/opsx-continue.md +114 -0
- package/.cursor/commands/opsx-explore.md +174 -0
- package/.cursor/commands/opsx-ff.md +94 -0
- package/.cursor/commands/opsx-new.md +69 -0
- package/.cursor/commands/opsx-onboard.md +525 -0
- package/.cursor/commands/opsx-sync.md +134 -0
- package/.cursor/commands/opsx-verify.md +164 -0
- package/.cursor/mcp.json +22 -0
- package/.cursor/skills/add-skill/SKILL.md +352 -0
- package/.cursor/skills/api-development/SKILL.md +560 -0
- package/.cursor/skills/architecture-design/SKILL.md +756 -0
- package/.cursor/skills/backend-annotations/SKILL.md +674 -0
- package/.cursor/skills/banana-image/CHANGELOG.md +37 -0
- package/.cursor/skills/banana-image/README.md +146 -0
- package/.cursor/skills/banana-image/SKILL.md +164 -0
- package/.cursor/skills/banana-image/assets/logo.png +0 -0
- package/.cursor/skills/banana-image/references/advanced-usage.md +189 -0
- package/.cursor/skills/banana-image/scripts/apply_template.py +125 -0
- package/.cursor/skills/banana-image/scripts/banana_image_exec.ts +412 -0
- package/.cursor/skills/banana-image/scripts/batch_prep.py +82 -0
- package/.cursor/skills/banana-image/scripts/package-lock.json +1437 -0
- package/.cursor/skills/banana-image/scripts/package.json +18 -0
- package/.cursor/skills/banana-image/scripts/requirements.txt +10 -0
- package/.cursor/skills/banana-image/templates/poster.json +22 -0
- package/.cursor/skills/banana-image/templates/product.json +17 -0
- package/.cursor/skills/banana-image/templates/social.json +22 -0
- package/.cursor/skills/banana-image/templates/thumbnail.json +17 -0
- package/.cursor/skills/brainstorm/SKILL.md +648 -0
- package/.cursor/skills/bug-detective/SKILL.md +1206 -0
- package/.cursor/skills/code-patterns/SKILL.md +590 -0
- package/.cursor/skills/collaborating-with-codex/SKILL.md +174 -0
- package/.cursor/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
- package/.cursor/skills/collaborating-with-gemini/SKILL.md +194 -0
- package/.cursor/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
- package/.cursor/skills/crud-development/SKILL.md +649 -0
- package/.cursor/skills/data-permission/SKILL.md +599 -0
- package/.cursor/skills/database-ops/SKILL.md +407 -0
- package/.cursor/skills/error-handler/SKILL.md +371 -0
- package/.cursor/skills/file-oss-management/SKILL.md +863 -0
- package/.cursor/skills/git-workflow/SKILL.md +375 -0
- package/.cursor/skills/json-serialization/SKILL.md +357 -0
- package/.cursor/skills/leniu-api-development/SKILL.md +803 -0
- package/.cursor/skills/leniu-architecture-design/SKILL.md +598 -0
- package/.cursor/skills/leniu-backend-annotations/SKILL.md +664 -0
- package/.cursor/skills/leniu-code-patterns/SKILL.md +365 -0
- package/.cursor/skills/leniu-crud-development/SKILL.md +1110 -0
- package/.cursor/skills/leniu-data-permission/SKILL.md +256 -0
- package/.cursor/skills/leniu-database-ops/SKILL.md +426 -0
- package/.cursor/skills/leniu-error-handler/SKILL.md +462 -0
- package/.cursor/skills/leniu-java-amount-handling/SKILL.md +461 -0
- package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
- package/.cursor/skills/leniu-java-concurrent/SKILL.md +400 -0
- package/.cursor/skills/leniu-java-entity/SKILL.md +751 -0
- package/.cursor/skills/leniu-java-export/SKILL.md +560 -0
- package/.cursor/skills/leniu-java-logging/SKILL.md +832 -0
- package/.cursor/skills/leniu-java-mq/SKILL.md +338 -0
- package/.cursor/skills/leniu-java-mybatis/SKILL.md +640 -0
- package/.cursor/skills/leniu-java-report-query-param/SKILL.md +291 -0
- package/.cursor/skills/leniu-java-task/SKILL.md +367 -0
- package/.cursor/skills/leniu-java-total-line/SKILL.md +195 -0
- package/.cursor/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
- package/.cursor/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
- package/.cursor/skills/leniu-mealtime/SKILL.md +215 -0
- package/.cursor/skills/leniu-redis-cache/SKILL.md +316 -0
- package/.cursor/skills/leniu-security-guard/SKILL.md +520 -0
- package/.cursor/skills/leniu-utils-toolkit/SKILL.md +380 -0
- package/.cursor/skills/openspec-apply-change/SKILL.md +156 -0
- package/.cursor/skills/openspec-archive-change/SKILL.md +114 -0
- package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +246 -0
- package/.cursor/skills/openspec-continue-change/SKILL.md +118 -0
- package/.cursor/skills/openspec-explore/SKILL.md +290 -0
- package/.cursor/skills/openspec-ff-change/SKILL.md +101 -0
- package/.cursor/skills/openspec-new-change/SKILL.md +74 -0
- package/.cursor/skills/openspec-onboard/SKILL.md +529 -0
- package/.cursor/skills/openspec-sync-specs/SKILL.md +138 -0
- package/.cursor/skills/openspec-verify-change/SKILL.md +168 -0
- package/.cursor/skills/performance-doctor/SKILL.md +627 -0
- package/.cursor/skills/project-navigator/SKILL.md +305 -0
- package/.cursor/skills/redis-cache/SKILL.md +839 -0
- package/.cursor/skills/scheduled-jobs/SKILL.md +633 -0
- package/.cursor/skills/security-guard/SKILL.md +748 -0
- package/.cursor/skills/sms-mail/SKILL.md +766 -0
- package/.cursor/skills/social-login/SKILL.md +668 -0
- package/.cursor/skills/store-pc/SKILL.md +366 -0
- package/.cursor/skills/task-tracker/SKILL.md +307 -0
- package/.cursor/skills/tech-decision/SKILL.md +393 -0
- package/.cursor/skills/tenant-management/SKILL.md +603 -0
- package/.cursor/skills/test-development/SKILL.md +755 -0
- package/.cursor/skills/ui-pc/SKILL.md +438 -0
- package/.cursor/skills/utils-toolkit/SKILL.md +615 -0
- package/.cursor/skills/websocket-sse/SKILL.md +716 -0
- package/.cursor/skills/workflow-engine/SKILL.md +676 -0
- package/AGENTS.md +669 -0
- package/CLAUDE.md +205 -0
- package/README.md +205 -0
- package/bin/index.js +179 -0
- package/init.sh +178 -0
- package/package.json +27 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: leniu-java-mybatis
|
|
3
|
+
description: |
|
|
4
|
+
leniu-tengyun-core 项目 MyBatis 使用规范。当编写 MyBatis Plus 代码或 MyBatis XML 映射文件时使用此 skill。
|
|
5
|
+
|
|
6
|
+
触发场景:
|
|
7
|
+
- 编写 Mapper 接口(extends BaseMapper)
|
|
8
|
+
- 使用 LambdaQueryWrapper 构建查询条件
|
|
9
|
+
- 编写 MyBatis XML 映射文件(动态 SQL、结果映射)
|
|
10
|
+
- 使用 MyBatis Plus 分页查询
|
|
11
|
+
- 处理租户隔离(@InterceptorIgnore)
|
|
12
|
+
|
|
13
|
+
触发词:MyBatis、MyBatisPlus、Mapper、LambdaQueryWrapper、LambdaQuery、XML映射、动态SQL、selectPage、BaseMapper、@Select、resultMap、租户隔离、delFlag
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# leniu-tengyun-core MyBatis 规范
|
|
17
|
+
|
|
18
|
+
## 项目特征
|
|
19
|
+
|
|
20
|
+
| 特征 | 说明 |
|
|
21
|
+
|------|------|
|
|
22
|
+
| **包名前缀** | `net.xnzn.core.*` |
|
|
23
|
+
| **JDK 版本** | 21 |
|
|
24
|
+
| **ORM 框架** | MyBatis-Plus + MyBatis |
|
|
25
|
+
| **Mapper XML 位置** | 与 Mapper 接口同目录(非 resources/mapper/) |
|
|
26
|
+
| **分页组件** | PageHelper (PageMethod.startPage) |
|
|
27
|
+
| **租户隔离** | 租户行级隔离 |
|
|
28
|
+
| **逻辑删除** | 1=删除,2=正常(与 RuoYi 相反) |
|
|
29
|
+
|
|
30
|
+
## Mapper 接口模板
|
|
31
|
+
|
|
32
|
+
### 基础 Mapper
|
|
33
|
+
|
|
34
|
+
```java
|
|
35
|
+
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
36
|
+
import net.xnzn.core.xxx.model.XxxEntity;
|
|
37
|
+
import org.apache.ibatis.annotations.Mapper;
|
|
38
|
+
|
|
39
|
+
@Mapper
|
|
40
|
+
public interface XxxMapper extends BaseMapper<XxxEntity> {
|
|
41
|
+
|
|
42
|
+
List<XxxVO> listByParam(@Param("param") XxxParam param);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 租户隔离忽略(方法级)
|
|
47
|
+
|
|
48
|
+
```java
|
|
49
|
+
import com.baomidou.mybatisplus.core.interceptor.InterceptorIgnore;
|
|
50
|
+
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
51
|
+
|
|
52
|
+
@Mapper
|
|
53
|
+
public interface XxxMapper extends BaseMapper<XxxEntity> {
|
|
54
|
+
|
|
55
|
+
@InterceptorIgnore(tenantLine = "true")
|
|
56
|
+
List<XxxVO> queryWithoutTenant(@Param("param") XxxParam param);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**说明**:`@InterceptorIgnore(tenantLine = "true")` 仅忽略特定方法的租户行级隔离。
|
|
61
|
+
|
|
62
|
+
### 全量忽略拦截器(类级别,来自 OrderInfoMapper 真实代码)
|
|
63
|
+
|
|
64
|
+
```java
|
|
65
|
+
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
66
|
+
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
67
|
+
import net.xnzn.framework.data.exists.BaseExistsMapper;
|
|
68
|
+
import org.apache.ibatis.annotations.Mapper;
|
|
69
|
+
|
|
70
|
+
@Mapper
|
|
71
|
+
@InterceptorIgnore // ✅ 无参数,类级别,跳过所有拦截器(含租户、数据权限等)
|
|
72
|
+
public interface XxxMapper extends BaseMapper<XxxEntity>, BaseExistsMapper<XxxEntity> {
|
|
73
|
+
|
|
74
|
+
// 自定义 XML 查询方法
|
|
75
|
+
List<XxxVO> listVoByIds(@Param("orderIds") List<Long> ids, @Param("tenantId") String tenantId);
|
|
76
|
+
|
|
77
|
+
@QueryExtension
|
|
78
|
+
List<XxxIdDateVO> queryXxx(@Param("param") XxxSearchParam param, @Param("permission") XxxUserPermissionDTO permission);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**说明**:
|
|
83
|
+
- `@InterceptorIgnore`(无参数)在**类级别**:整个 Mapper 的所有方法都跳过 MyBatis-Plus 所有拦截器(租户隔离、数据权限等),需要自行在 SQL 中控制
|
|
84
|
+
- `BaseExistsMapper<XxxEntity>` 提供 `existsOne(Wrapper)` 方法,用于检查记录是否存在,比 `selectCount > 0` 更高效
|
|
85
|
+
- 适用于:订单等核心表(数据量大、需要全量跨租户查询的场景)
|
|
86
|
+
|
|
87
|
+
### BaseExistsMapper 使用示例
|
|
88
|
+
|
|
89
|
+
```java
|
|
90
|
+
// 检查订单是否存在
|
|
91
|
+
boolean exists = baseMapper.existsOne(
|
|
92
|
+
Wrappers.lambdaQuery(OrderInfo.class)
|
|
93
|
+
.eq(OrderInfo::getMacOrderId, macOrderId)
|
|
94
|
+
.eq(OrderInfo::getDelFlag, 2)
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Entity 实体类模板
|
|
99
|
+
|
|
100
|
+
### 基础 Entity
|
|
101
|
+
|
|
102
|
+
```java
|
|
103
|
+
import com.baomidou.mybatisplus.annotation.*;
|
|
104
|
+
import io.swagger.annotations.ApiModel;
|
|
105
|
+
import io.swagger.annotations.ApiModelProperty;
|
|
106
|
+
import lombok.Data;
|
|
107
|
+
|
|
108
|
+
import java.time.LocalDateTime;
|
|
109
|
+
|
|
110
|
+
@Data
|
|
111
|
+
@TableName(value = "table_name", autoResultMap = true)
|
|
112
|
+
public class XxxEntity {
|
|
113
|
+
|
|
114
|
+
@TableId
|
|
115
|
+
@ApiModelProperty(value = "主键ID")
|
|
116
|
+
private Long id;
|
|
117
|
+
|
|
118
|
+
@ApiModelProperty(value = "删除标识(1-删除,2-正常)")
|
|
119
|
+
private Integer delFlag;
|
|
120
|
+
|
|
121
|
+
@ApiModelProperty(value = "创建人")
|
|
122
|
+
private String crby;
|
|
123
|
+
|
|
124
|
+
@ApiModelProperty(value = "创建时间")
|
|
125
|
+
private LocalDateTime crtime;
|
|
126
|
+
|
|
127
|
+
@ApiModelProperty(value = "更新人")
|
|
128
|
+
private String upby;
|
|
129
|
+
|
|
130
|
+
@ApiModelProperty(value = "更新时间")
|
|
131
|
+
private LocalDateTime uptime;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 自动填充字段
|
|
136
|
+
|
|
137
|
+
```java
|
|
138
|
+
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
139
|
+
import com.baomidou.mybatisplus.annotation.TableField;
|
|
140
|
+
import com.baomidou.mybatisplus.annotation.TableId;
|
|
141
|
+
import com.baomidou.mybatisplus.annotation.TableName;
|
|
142
|
+
import lombok.Data;
|
|
143
|
+
|
|
144
|
+
import java.time.LocalDateTime;
|
|
145
|
+
|
|
146
|
+
@Data
|
|
147
|
+
@TableName(value = "table_name", autoResultMap = true)
|
|
148
|
+
public class XxxEntity {
|
|
149
|
+
|
|
150
|
+
@TableId
|
|
151
|
+
private Long id;
|
|
152
|
+
|
|
153
|
+
// 插入时自动填充
|
|
154
|
+
@TableField(fill = FieldFill.INSERT)
|
|
155
|
+
private String crby;
|
|
156
|
+
|
|
157
|
+
@TableField(fill = FieldFill.INSERT)
|
|
158
|
+
private LocalDateTime crtime;
|
|
159
|
+
|
|
160
|
+
// 插入或更新时自动填充
|
|
161
|
+
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
162
|
+
private String upby;
|
|
163
|
+
|
|
164
|
+
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
165
|
+
private LocalDateTime uptime;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## LambdaQuery 使用
|
|
170
|
+
|
|
171
|
+
### 条件查询
|
|
172
|
+
|
|
173
|
+
```java
|
|
174
|
+
import cn.hutool.core.util.StrUtil;
|
|
175
|
+
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
176
|
+
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
177
|
+
|
|
178
|
+
// 条件查询
|
|
179
|
+
List<XxxEntity> list = mapper.selectList(
|
|
180
|
+
Wrappers.lambdaQuery(XxxEntity.class)
|
|
181
|
+
.eq(XxxEntity::getStatus, 1)
|
|
182
|
+
.eq(XxxEntity::getDelFlag, 2) // 2=正常
|
|
183
|
+
.in(XxxEntity::getId, idList)
|
|
184
|
+
.like(StrUtil.isNotBlank(name), XxxEntity::getName, name)
|
|
185
|
+
.orderByDesc(XxxEntity::getCrtime)
|
|
186
|
+
);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 字段非空判断
|
|
190
|
+
|
|
191
|
+
```java
|
|
192
|
+
import cn.hutool.core.util.ObjectUtil;
|
|
193
|
+
import cn.hutool.core.util.StrUtil;
|
|
194
|
+
|
|
195
|
+
LambdaQueryWrapper<XxxEntity> wrapper = Wrappers.lambdaQuery();
|
|
196
|
+
|
|
197
|
+
// 使用 Hutool 工具类
|
|
198
|
+
wrapper.eq(ObjectUtil.isNotNull(status), XxxEntity::getStatus, status);
|
|
199
|
+
wrapper.like(StrUtil.isNotBlank(keyword), XxxEntity::getName, keyword);
|
|
200
|
+
wrapper.ge(startDate != null, XxxEntity::getCrtime, startDate);
|
|
201
|
+
wrapper.le(endDate != null, XxxEntity::getCrtime, endDate);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## XML 编写模板
|
|
205
|
+
|
|
206
|
+
### 基本结构
|
|
207
|
+
|
|
208
|
+
```xml
|
|
209
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
210
|
+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
211
|
+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
212
|
+
<mapper namespace="net.xnzn.core.xxx.mapper.XxxMapper">
|
|
213
|
+
|
|
214
|
+
<select id="listByParam" resultType="net.xnzn.core.xxx.vo.XxxVO">
|
|
215
|
+
SELECT
|
|
216
|
+
t.id,
|
|
217
|
+
t.name,
|
|
218
|
+
t.status
|
|
219
|
+
FROM table_name t
|
|
220
|
+
<where>
|
|
221
|
+
t.del_flag = 2
|
|
222
|
+
<if test="param.status != null">
|
|
223
|
+
AND t.status = #{param.status}
|
|
224
|
+
</if>
|
|
225
|
+
<if test="param.keyword != null and param.keyword != ''">
|
|
226
|
+
AND t.name LIKE CONCAT('%', #{param.keyword}, '%')
|
|
227
|
+
</if>
|
|
228
|
+
</where>
|
|
229
|
+
ORDER BY t.crtime DESC
|
|
230
|
+
</select>
|
|
231
|
+
</mapper>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### XML 编写规范
|
|
235
|
+
|
|
236
|
+
| 规则 | 说明 |
|
|
237
|
+
|------|------|
|
|
238
|
+
| 禁止 `SELECT *` | 必须明确指定字段 |
|
|
239
|
+
| 使用 `<where>` | 自动处理 AND 前缀 |
|
|
240
|
+
| 使用 `<if>` | 动态条件判断 |
|
|
241
|
+
| 特殊字符包裹 | `<![CDATA[ ]]>` 包含 `<`、`>` 等 |
|
|
242
|
+
| 参数占位符 | 使用 `#{}` 而非 `${}` 防止 SQL 注入 |
|
|
243
|
+
| 逻辑删除条件 | `del_flag = 2` 表示正常数据 |
|
|
244
|
+
|
|
245
|
+
### 常用 XML 标签
|
|
246
|
+
|
|
247
|
+
```xml
|
|
248
|
+
<!-- 条件判断 -->
|
|
249
|
+
<if test="param.status != null">
|
|
250
|
+
AND t.status = #{param.status}
|
|
251
|
+
</if>
|
|
252
|
+
|
|
253
|
+
<!-- 集合遍历(IN 查询) -->
|
|
254
|
+
<if test="param.ids != null and param.ids.size() > 0">
|
|
255
|
+
AND t.id IN
|
|
256
|
+
<foreach collection="param.ids" item="id" open="(" separator="," close=")">
|
|
257
|
+
#{id}
|
|
258
|
+
</foreach>
|
|
259
|
+
</if>
|
|
260
|
+
|
|
261
|
+
<!-- 多条件 OR -->
|
|
262
|
+
<if test="param.keyword != null and param.keyword != ''">
|
|
263
|
+
AND (
|
|
264
|
+
t.name LIKE CONCAT('%', #{param.keyword}, '%')
|
|
265
|
+
OR t.code LIKE CONCAT('%', #{param.keyword}, '%')
|
|
266
|
+
)
|
|
267
|
+
</if>
|
|
268
|
+
|
|
269
|
+
<!-- 时间范围 -->
|
|
270
|
+
<if test="param.startDate != null">
|
|
271
|
+
AND t.crtime >= #{param.startDate}
|
|
272
|
+
</if>
|
|
273
|
+
<if test="param.endDate != null">
|
|
274
|
+
AND t.crtime <= #{param.endDate}
|
|
275
|
+
</if>
|
|
276
|
+
|
|
277
|
+
<!-- 特殊字符 -->
|
|
278
|
+
< <!-- 小于 < -->
|
|
279
|
+
> <!-- 大于 > -->
|
|
280
|
+
& <!-- 和 & -->
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Mapper XML 位置
|
|
284
|
+
|
|
285
|
+
### leniu 项目规范
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
net.xnzn.core.xxx.mapper
|
|
289
|
+
├── XxxMapper.java # Mapper 接口
|
|
290
|
+
└── XxxMapper.xml # XML 文件(与接口同目录)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**注意**:leniu 项目的 Mapper XML 文件放在与 Mapper 接口同目录下,不是 `resources/mapper/`。
|
|
294
|
+
|
|
295
|
+
## Service 中 Mapper 注入规范
|
|
296
|
+
|
|
297
|
+
### 字段命名(来自 OrderInfoService 真实代码)
|
|
298
|
+
|
|
299
|
+
```java
|
|
300
|
+
@Slf4j
|
|
301
|
+
@Service
|
|
302
|
+
@Validated
|
|
303
|
+
public class XxxService {
|
|
304
|
+
|
|
305
|
+
// ✅ 正确:Mapper 字段命名为 baseMapper
|
|
306
|
+
@Autowired
|
|
307
|
+
private XxxMapper baseMapper;
|
|
308
|
+
|
|
309
|
+
// 其他跨模块依赖用 @Lazy 避免循环依赖
|
|
310
|
+
@Autowired
|
|
311
|
+
@Lazy
|
|
312
|
+
private XxxDetailService xxxDetailService;
|
|
313
|
+
|
|
314
|
+
public XxxEntity getOne(Long id) {
|
|
315
|
+
return baseMapper.selectById(id);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
public List<XxxVO> listByIds(List<Long> ids) {
|
|
319
|
+
return baseMapper.listVoByIds(ids, TenantContextHolder.getTenantId());
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
public boolean exists(String macOrderId) {
|
|
323
|
+
return baseMapper.existsOne(
|
|
324
|
+
Wrappers.lambdaQuery(XxxEntity.class)
|
|
325
|
+
.eq(XxxEntity::getMacOrderId, macOrderId)
|
|
326
|
+
.eq(XxxEntity::getDelFlag, 2)
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**规范要点**:
|
|
333
|
+
- Service **无接口**(不用 `IXxxService`),直接 `@Service` 类
|
|
334
|
+
- Service 类上加 `@Validated` 支持方法参数的 `@NotNull` 校验
|
|
335
|
+
- Mapper 注入字段名统一用 `baseMapper`(不用 `xxxMapper`)
|
|
336
|
+
- 跨模块依赖(其他 Service/Client)用 `@Autowired @Lazy` 防循环依赖
|
|
337
|
+
|
|
338
|
+
## 分页查询
|
|
339
|
+
|
|
340
|
+
### PageHelper 分页
|
|
341
|
+
|
|
342
|
+
```java
|
|
343
|
+
import com.github.pagehelper.page.PageMethod;
|
|
344
|
+
import net.xnzn.core.common.page.PageVO;
|
|
345
|
+
|
|
346
|
+
public PageVO<XxxVO> pageList(XxxParam param) {
|
|
347
|
+
// ✅ 正确:传入 PageDTO 对象(非 pageNum/pageSize 拆分)
|
|
348
|
+
if (Objects.nonNull(param.getPage())) {
|
|
349
|
+
PageMethod.startPage(param.getPage());
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// 执行查询,Mapper 返回 List 即可,PageHelper 自动附加分页信息
|
|
353
|
+
List<XxxVO> records = xxxMapper.listByParam(param);
|
|
354
|
+
|
|
355
|
+
// 包装为 PageVO(自动提取 total 等信息)
|
|
356
|
+
return PageVO.of(records);
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**注意**:
|
|
361
|
+
- `PageMethod.startPage(param.getPage())` 传 `PageDTO` 对象,不要拆开传 `pageNum`/`pageSize`
|
|
362
|
+
- Mapper 方法返回 `List<XxxVO>` 即可,PageHelper 拦截器自动处理分页
|
|
363
|
+
- `PageVO.of(records)` 自动从 PageHelper 的 Page 代理对象提取总数等信息
|
|
364
|
+
|
|
365
|
+
### Param 分页参数
|
|
366
|
+
|
|
367
|
+
```java
|
|
368
|
+
@Data
|
|
369
|
+
public class XxxParam implements Serializable {
|
|
370
|
+
|
|
371
|
+
@ApiModelProperty(value = "分页参数", required = true)
|
|
372
|
+
@NotNull(message = "分页参数不能为空")
|
|
373
|
+
private PageDTO page;
|
|
374
|
+
|
|
375
|
+
@ApiModelProperty("关键字")
|
|
376
|
+
private String keyword;
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## 报表 Mapper 规范(来自 ReportAnalysisTurnoverMapper 真实代码)
|
|
381
|
+
|
|
382
|
+
报表模块的 Mapper **不继承 BaseMapper**(纯 SQL 查询,无 CRUD),固定三个参数:`param`、`authPO`、`dataPermission`:
|
|
383
|
+
|
|
384
|
+
```java
|
|
385
|
+
@Mapper
|
|
386
|
+
public interface ReportXxxMapper {
|
|
387
|
+
|
|
388
|
+
// ✅ 分页列表查询(PageHelper 拦截,方法返回 List)
|
|
389
|
+
List<XxxVO> listSummary(
|
|
390
|
+
@Param("param") XxxParam param,
|
|
391
|
+
@Param("authPO") MgrUserAuthPO authPO,
|
|
392
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
// ✅ 合计行查询(不分页,返回单个汇总 VO)
|
|
396
|
+
XxxVO getSummaryTotal(
|
|
397
|
+
@Param("param") XxxParam param,
|
|
398
|
+
@Param("authPO") MgrUserAuthPO authPO,
|
|
399
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
// ✅ 按日/按月分组(对应 dateType 参数)
|
|
403
|
+
List<XxxVO> listSummaryByDay(
|
|
404
|
+
@Param("param") XxxParam param,
|
|
405
|
+
@Param("authPO") MgrUserAuthPO authPO,
|
|
406
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
407
|
+
);
|
|
408
|
+
List<XxxVO> listSummaryByMonth(
|
|
409
|
+
@Param("param") XxxParam param,
|
|
410
|
+
@Param("authPO") MgrUserAuthPO authPO,
|
|
411
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
// ✅ 汇总数据(总金额、人次等)
|
|
415
|
+
ReportTurnoverPO getTurnoverTotal(
|
|
416
|
+
@Param("param") XxxParam param,
|
|
417
|
+
@Param("authPO") MgrUserAuthPO authPO,
|
|
418
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
// ✅ 排行榜类(不需要 authPO 时可省略)
|
|
422
|
+
List<RankVO> getXxxRank(
|
|
423
|
+
@Param("param") RankParam param,
|
|
424
|
+
@Param("dataPermission") ReportDataPermissionParam dataPermission
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**报表 Mapper 关键规则**:
|
|
430
|
+
1. `@Mapper` 注解,**不继承 BaseMapper**(报表无 CRUD)
|
|
431
|
+
2. 所有参数必须加 `@Param`,顺序:`param` → `authPO` → `dataPermission`
|
|
432
|
+
3. 分页列表返回 `List<VO>`,由 Service 层调用 `PageMethod.startPage()` 控制
|
|
433
|
+
4. 合计行返回单个 PO/VO 对象
|
|
434
|
+
5. COUNT 方法(`listXxx_COUNT`)配合 `CompletableFuture` 并发使用
|
|
435
|
+
|
|
436
|
+
**命名规律**:
|
|
437
|
+
- 分页数据方法:`listXxx()`
|
|
438
|
+
- 对应 COUNT 方法:`listXxx_COUNT()`(下划线 + COUNT)
|
|
439
|
+
- 合计行方法:`getSummaryTotal()` / `getSummaryXxxTotal()`
|
|
440
|
+
- 按维度变体:`listXxxByDay()` / `listXxxByDay_COUNT()`
|
|
441
|
+
|
|
442
|
+
## 合计行查询
|
|
443
|
+
|
|
444
|
+
### Mapper 接口(普通 CRUD 模块)
|
|
445
|
+
|
|
446
|
+
```java
|
|
447
|
+
@Mapper
|
|
448
|
+
public interface XxxMapper extends BaseMapper<XxxEntity> {
|
|
449
|
+
|
|
450
|
+
List<XxxVO> listByParam(@Param("param") XxxParam param);
|
|
451
|
+
|
|
452
|
+
XxxVO getSummaryTotal(@Param("param") XxxParam param);
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### XML 实现
|
|
457
|
+
|
|
458
|
+
```xml
|
|
459
|
+
<!-- 列表查询 -->
|
|
460
|
+
<select id="listByParam" resultType="XxxVO">
|
|
461
|
+
SELECT
|
|
462
|
+
id,
|
|
463
|
+
name,
|
|
464
|
+
amount,
|
|
465
|
+
count
|
|
466
|
+
FROM table_name
|
|
467
|
+
<where>...</where>
|
|
468
|
+
ORDER BY id DESC
|
|
469
|
+
</select>
|
|
470
|
+
|
|
471
|
+
<!-- 合计查询:只返回数值字段 -->
|
|
472
|
+
<select id="getSummaryTotal" resultType="XxxVO">
|
|
473
|
+
SELECT
|
|
474
|
+
SUM(amount) AS amount,
|
|
475
|
+
SUM(count) AS count
|
|
476
|
+
FROM table_name
|
|
477
|
+
<where>...</where>
|
|
478
|
+
</select>
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**核心原则**:合计行 SQL 只返回需要合计的数值字段,不返回非数值字段(如名称、日期等)。
|
|
482
|
+
|
|
483
|
+
### 常用合计函数
|
|
484
|
+
|
|
485
|
+
| 函数 | 用途 | 示例 |
|
|
486
|
+
|------|------|------|
|
|
487
|
+
| `SUM()` | 求和 | `SUM(amount)` |
|
|
488
|
+
| `COUNT()` | 计数 | `COUNT(*)` |
|
|
489
|
+
| `AVG()` | 平均值 | `AVG(price)` |
|
|
490
|
+
| `MAX()` | 最大值 | `MAX(amount)` |
|
|
491
|
+
| `MIN()` | 最小值 | `MIN(amount)` |
|
|
492
|
+
|
|
493
|
+
### 特殊处理
|
|
494
|
+
|
|
495
|
+
```xml
|
|
496
|
+
<!-- 除零处理 -->
|
|
497
|
+
CASE
|
|
498
|
+
WHEN SUM(count) = 0 THEN 0
|
|
499
|
+
ELSE SUM(amount) / SUM(count)
|
|
500
|
+
END AS avgAmount
|
|
501
|
+
|
|
502
|
+
<!-- 按维度平均 -->
|
|
503
|
+
CASE
|
|
504
|
+
WHEN SUM(staff_count) = 0 THEN 0
|
|
505
|
+
ELSE SUM(avg_salary) / COUNT(DISTINCT tenant_id)
|
|
506
|
+
END AS avgSalary
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
## 租户隔离
|
|
510
|
+
|
|
511
|
+
### 自动隔离
|
|
512
|
+
|
|
513
|
+
默认情况下,MyBatis-Plus 会自动为查询添加租户条件:
|
|
514
|
+
|
|
515
|
+
```sql
|
|
516
|
+
SELECT * FROM table_name WHERE del_flag = 2 AND tenant_id = ?
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### 忽略租户隔离
|
|
520
|
+
|
|
521
|
+
```java
|
|
522
|
+
@InterceptorIgnore(tenantLine = "true")
|
|
523
|
+
List<XxxVO> queryWithoutTenant(@Param("param") XxxParam param);
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**使用场景**:
|
|
527
|
+
- 查询系统级配置数据
|
|
528
|
+
- 跨租户数据汇总
|
|
529
|
+
- 导出所有租户数据
|
|
530
|
+
|
|
531
|
+
## 逻辑删除
|
|
532
|
+
|
|
533
|
+
### 删除标识
|
|
534
|
+
|
|
535
|
+
| 值 | 含义 |
|
|
536
|
+
|-----|------|
|
|
537
|
+
| 1 | 已删除 |
|
|
538
|
+
| 2 | 正常 |
|
|
539
|
+
|
|
540
|
+
**注意**:与 RuoYi-Vue-Plus 相反(RuoYi: 0=正常, 2=删除)
|
|
541
|
+
|
|
542
|
+
### 查询过滤
|
|
543
|
+
|
|
544
|
+
```java
|
|
545
|
+
// 查询时自动过滤已删除数据
|
|
546
|
+
LambdaQueryWrapper<XxxEntity> wrapper = Wrappers.lambdaQuery();
|
|
547
|
+
wrapper.eq(XxxEntity::getDelFlag, 2); // 2=正常
|
|
548
|
+
|
|
549
|
+
// XML 中手动添加
|
|
550
|
+
SELECT * FROM table_name WHERE del_flag = 2
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
## 常用工具类
|
|
554
|
+
|
|
555
|
+
### Hutool 工具类
|
|
556
|
+
|
|
557
|
+
```java
|
|
558
|
+
import cn.hutool.core.util.ObjectUtil;
|
|
559
|
+
import cn.hutool.core.util.StrUtil;
|
|
560
|
+
import cn.hutool.core.collection.CollUtil;
|
|
561
|
+
|
|
562
|
+
// 对象判空
|
|
563
|
+
if (ObjectUtil.isNull(entity)) { }
|
|
564
|
+
if (ObjectUtil.isNotNull(entity)) { }
|
|
565
|
+
|
|
566
|
+
// 字符串判空
|
|
567
|
+
if (StrUtil.isBlank(str)) { }
|
|
568
|
+
if (StrUtil.isNotBlank(str)) { }
|
|
569
|
+
|
|
570
|
+
// 集合判空
|
|
571
|
+
if (CollUtil.isEmpty(list)) { }
|
|
572
|
+
if (CollUtil.isNotEmpty(list)) { }
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### MyBatis-Plus 工具类
|
|
576
|
+
|
|
577
|
+
```java
|
|
578
|
+
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
579
|
+
|
|
580
|
+
// 创建 Lambda 查询包装器
|
|
581
|
+
LambdaQueryWrapper<XxxEntity> wrapper = Wrappers.lambdaQuery();
|
|
582
|
+
LambdaUpdateWrapper<XxxEntity> updateWrapper = Wrappers.lambdaUpdate();
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
## 常见错误
|
|
586
|
+
|
|
587
|
+
### 错误1:使用 RuoYi 的 TenantEntity
|
|
588
|
+
|
|
589
|
+
```java
|
|
590
|
+
// ❌ 错误:使用 RuoYi 的基类
|
|
591
|
+
import org.dromara.common.mybatis.core.domain.TenantEntity;
|
|
592
|
+
|
|
593
|
+
// ✅ 正确:leniu 项目使用自定义 Entity 或无基类
|
|
594
|
+
@Data
|
|
595
|
+
@TableName("table_name")
|
|
596
|
+
public class XxxEntity {
|
|
597
|
+
@TableId
|
|
598
|
+
private Long id;
|
|
599
|
+
}
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### 错误2:delFlag 判断错误
|
|
603
|
+
|
|
604
|
+
```java
|
|
605
|
+
// ❌ 错误:使用 RuoYi 的值
|
|
606
|
+
wrapper.eq(XxxEntity::getDelFlag, 0);
|
|
607
|
+
|
|
608
|
+
// ✅ 正确:leniu 使用 2 表示正常
|
|
609
|
+
wrapper.eq(XxxEntity::getDelFlag, 2);
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### 错误3:XML 路径错误
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
# ❌ 错误:resources/mapper/ 目录
|
|
616
|
+
net.xnzn.core.xxx.mapper
|
|
617
|
+
└── XxxMapper.java
|
|
618
|
+
src/main/resources/mapper/
|
|
619
|
+
└── XxxMapper.xml
|
|
620
|
+
|
|
621
|
+
# ✅ 正确:XML 与接口同目录
|
|
622
|
+
net.xnzn.core.xxx.mapper
|
|
623
|
+
├── XxxMapper.java
|
|
624
|
+
└── XxxMapper.xml
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### 错误4:MapstructUtils 工具类
|
|
628
|
+
|
|
629
|
+
```java
|
|
630
|
+
// ❌ 错误:使用 RuoYi 的工具类
|
|
631
|
+
import org.dromara.common.core.utils.MapstructUtils;
|
|
632
|
+
|
|
633
|
+
// ✅ 正确:leniu 使用 Hutool
|
|
634
|
+
import cn.hutool.core.bean.BeanUtil;
|
|
635
|
+
Target target = BeanUtil.copyProperties(source, Target.class);
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
## 参考文档
|
|
639
|
+
|
|
640
|
+
详见:[leniu-tengyun-core 源码](/Users/xujiajun/Developer/gongsi_proj/core/leniu-tengyun-core)
|