# 数据访问层 **本文引用的文件** - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本章节面向数据访问层,围绕以下目标展开: - 接口设计:CrmBaseMapper 的设计与职责边界 - MyBatis Plus 配置:插件、填充器、ID 生成器等关键配置 - SQL 注入器:自定义通用 SQL 能力扩展 - 高级特性:连接池、分页、乐观锁、逻辑删除等 - 性能优化:SQL 监控、调试技巧、批量操作建议 ## 项目结构 数据访问相关代码主要分布在 crm-base(基础能力)与业务模块(如 crm-auth、crm-file)的 mapper/service 中。核心配置文件集中在各模块 resources 下的 application.yml。 ```mermaid graph TB subgraph "基础模块 crm-base" A["CrmBaseMapper
定义通用 Mapper 接口"] B["MybatisPlusConfig
MP 全局配置"] C["CrmSqlInjector
自定义 SQL 注入器"] D["MetaObjectFillHandler
自动填充处理器"] E["CustomIdGenerator / SnowflakeIdWorker
ID 生成策略"] F["BaseEntity / OwnedEntity
实体基类"] G["BaseServiceImpl / IBaseService
基础服务实现"] end subgraph "应用模块" H["crm-app / crm-auth / crm-file
业务模块"] I["application.yml
数据库与 MP 配置"] end A --> B C --> B D --> B E --> B F --> A G --> A H --> A H --> B H --> I ``` 图表来源 - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) 章节来源 - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 核心组件 - CrmBaseMapper:为所有业务 Mapper 提供统一的基础方法扩展点,便于在公共层增强查询、更新、分页等行为。 - MybatisPlusConfig:集中配置 MyBatis Plus 的分页、乐观锁、逻辑删除、全局填充、ID 生成器、SQL 注入器等。 - CrmSqlInjector:通过 MyBatis Plus 的 ISqlInjector 机制,向 Mapper 动态注入自定义 SQL 片段或方法。 - MetaObjectFillHandler:基于 MetaObjectHandler 实现字段自动填充(如创建时间、更新时间、创建人等)。 - CustomIdGenerator + SnowflakeIdWorker:分布式 ID 生成策略,结合 SnowflakeProperties 进行参数化配置。 - BaseEntity / OwnedEntity:实体基类,承载通用字段(如 id、逻辑删除标记、版本控制等),配合 MP 注解使用。 - BaseServiceImpl / IBaseService:基础 Service 抽象,封装常用 CRUD、分页、事务等能力,减少重复代码。 章节来源 - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) ## 架构总览 数据访问层以 MyBatis Plus 为核心,结合 Spring Boot 配置与自定义扩展,形成“接口—配置—注入器—处理器—实体—服务”的完整链路。 ```mermaid sequenceDiagram participant App as "应用启动" participant MP as "MybatisPlusConfig" participant INJ as "CrmSqlInjector" participant H as "MetaObjectFillHandler" participant ID as "CustomIdGenerator" participant DB as "数据库" App->>MP : 初始化 MyBatis Plus MP->>INJ : 注册自定义 SQL 注入器 MP->>H : 注册自动填充处理器 MP->>ID : 注册分布式 ID 生成器 Note over MP,ID : 完成全局配置 App->>DB : 建立连接池并执行 SQL ``` 图表来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 详细组件分析 ### CrmBaseMapper 接口设计 - 定位:作为所有业务 Mapper 的父接口,用于统一扩展通用方法或拦截点。 - 设计要点: - 与 MP 的 BaseMapper 协同,避免覆盖 MP 内置方法导致行为不一致。 - 可在此声明需要由 CrmSqlInjector 注入的自定义方法,保持接口清晰。 - 与 BaseEntity 字段约定保持一致,确保自动填充、逻辑删除、乐观锁生效。 ```mermaid classDiagram class CrmBaseMapper { <> + "扩展通用方法" } class BaseMapper { <> + "CRUD 基础方法" } class BaseEntity { + "id" + "逻辑删除字段" + "版本控制字段" + "审计字段" } CrmBaseMapper <|-- 业务Mapper : "继承" BaseEntity <.. 业务实体 : "继承" ``` 图表来源 - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) 章节来源 - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) ### MyBatis Plus 配置 - 全局配置项: - 分页插件:启用分页拦截器,支持 Page、IPage 等 API。 - 乐观锁插件:基于版本号字段防止并发覆盖。 - 逻辑删除:对删除操作进行软删除处理。 - 自动填充:基于 MetaObjectHandler 设置审计字段。 - ID 生成器:采用分布式雪花算法生成唯一 ID。 - SQL 注入器:通过 CrmSqlInjector 注入自定义 SQL。 - 配置入口:MybatisPlusConfig 中注册上述组件。 ```mermaid flowchart TD Start(["启动"]) --> LoadCfg["加载 application.yml"] LoadCfg --> InitMP["初始化 MyBatis Plus"] InitMP --> RegisterPlugins["注册插件
分页/乐观锁/逻辑删除"] InitMP --> RegisterHandlers["注册处理器
自动填充/ID生成"] InitMP --> RegisterInjector["注册注入器
自定义 SQL"] RegisterPlugins --> Ready(["就绪"]) RegisterHandlers --> Ready RegisterInjector --> Ready ``` 图表来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) 章节来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ### SQL 注入器功能(CrmSqlInjector) - 作用:在 MP 启动时,将自定义 SQL 片段或方法注入到 Mapper 接口,减少样板代码。 - 典型用法: - 注入批量插入/更新方法。 - 注入复杂条件查询方法。 - 注入跨表关联查询方法。 - 注意事项: - 注入的方法名需与 Mapper 接口声明一致。 - SQL 片段应复用性强、参数化明确,避免硬编码。 ```mermaid sequenceDiagram participant MP as "MyBatis Plus" participant INJ as "CrmSqlInjector" participant MAP as "业务Mapper" MP->>INJ : 调用 getCustomSqlList() INJ-->>MP : 返回自定义 SQL 列表 MP->>MAP : 将自定义方法绑定到 Mapper Note over MP,MAP : 注入完成后即可调用 ``` 图表来源 - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) 章节来源 - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) ### 自动填充处理器(MetaObjectFillHandler) - 触发时机:insert、update 等操作前。 - 常见字段: - 创建时间、创建人 - 更新时间、更新人 - 租户/部门标识(如需) - 实现要点: - 区分 insert/update 场景。 - 从安全上下文获取当前用户信息。 - 避免覆盖业务显式设置的值。 ```mermaid flowchart TD Enter(["进入填充流程"]) --> OpType{"操作类型"} OpType --> |新增| FillCreate["填充创建时间/创建人"] OpType --> |修改| FillUpdate["填充更新时间/更新人"] FillCreate --> Exit(["结束"]) FillUpdate --> Exit ``` 图表来源 - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) 章节来源 - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) ### ID 生成策略(CustomIdGenerator + SnowflakeIdWorker) - 目标:保证分布式环境下主键唯一且有序。 - 组成: - CustomIdGenerator:对接 MP 的 IdGenerator 接口。 - SnowflakeIdWorker:雪花算法实现,结合 SnowflakeProperties 配置机器位/序列位等。 - 使用方式:在实体主键字段上指定策略或直接全局配置。 ```mermaid classDiagram class CustomIdGenerator { + "generateId(entity)" } class SnowflakeIdWorker { + "nextId()" } class SnowflakeProperties { + "workerId" + "datacenterId" + "sequenceBits" } CustomIdGenerator --> SnowflakeIdWorker : "调用" SnowflakeIdWorker --> SnowflakeProperties : "读取配置" ``` 图表来源 - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) 章节来源 - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) ### 实体基类与审计字段(BaseEntity / OwnedEntity) - BaseEntity:提供 id、逻辑删除标记、版本控制、审计字段等通用属性。 - OwnedEntity:在 BaseEntity 基础上增加数据归属字段(如所属部门/租户)。 - 与 MP 集成: - 逻辑删除字段配合 @TableLogic。 - 版本控制字段配合 @Version。 - 审计字段配合 MetaObjectFillHandler。 ```mermaid classDiagram class BaseEntity { + "id" + "deleted" + "version" + "createTime" + "updateTime" + "createBy" + "updateBy" } class OwnedEntity { + "ownerDeptId" + "ownerUserId" } BaseEntity <|-- OwnedEntity : "继承" ``` 图表来源 - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) 章节来源 - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) ### 基础服务层(BaseServiceImpl / IBaseService) - 职责:封装通用 CRUD、分页、批量操作、事务管理等。 - 优势: - 减少 Service 层样板代码。 - 统一异常与结果包装。 - 便于后续扩展(如缓存、审计、权限过滤)。 ```mermaid classDiagram class IBaseService { + "分页查询" + "批量保存" + "条件更新" } class BaseServiceImpl { + "实现 IBaseService" + "封装 MP 操作" } IBaseService <|.. BaseServiceImpl : "实现" ``` 图表来源 - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) 章节来源 - [IBaseService.java](file://crm-base/src/main/java/com/crm/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) ## 依赖关系分析 - 组件耦合: - MybatisPlusConfig 是中心枢纽,聚合插件、处理器、注入器、ID 生成器。 - CrmBaseMapper 与 BaseEntity 共同约束 Mapper 与实体的契约。 - BaseServiceImpl 依赖 CrmBaseMapper 提供的扩展能力。 - 外部依赖: - 数据库连接池(由 application.yml 配置)。 - MyBatis Plus 生态(分页、乐观锁、逻辑删除等)。 ```mermaid graph LR CFG["MybatisPlusConfig"] --> PLG["插件集合"] CFG --> HND["处理器集合"] CFG --> INJ["CrmSqlInjector"] CFG --> IDG["CustomIdGenerator"] MAP["业务Mapper"] --> CRMB["CrmBaseMapper"] SVC["BaseServiceImpl"] --> MAP ENT["BaseEntity/OwnedEntity"] --> MAP ``` 图表来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) 章节来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/service/impl/BaseServiceImpl.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) ## 性能考虑 - 连接池配置 - 合理设置最大连接数、最小空闲连接、连接超时等,避免连接耗尽或频繁创建销毁。 - 根据业务峰值与数据库承载能力调优。 - 分页插件 - 使用 MP 分页插件进行物理分页,避免全量拉取。 - 注意排序字段索引命中,避免回表扫描。 - 乐观锁 - 在高并发写场景下,通过版本号字段减少冲突覆盖。 - 失败重试策略需结合业务幂等性设计。 - 逻辑删除 - 查询时自动追加删除条件,避免脏数据。 - 定期归档或删除历史数据,控制表膨胀。 - SQL 监控与调试 - 开启 SQL 日志输出,关注慢查询与执行计划。 - 使用 EXPLAIN 分析复杂查询,必要时添加索引。 - 批量操作 - 优先使用批量插入/更新,减少网络往返。 - 注意事务大小,避免长事务导致锁竞争。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 常见问题 - 自动填充未生效:检查 MetaObjectFillHandler 是否注册、字段命名是否与实体一致。 - 乐观锁冲突:确认 version 字段是否正确参与更新条件。 - 逻辑删除失效:确认实体字段与 @TableLogic 配置一致。 - ID 生成异常:检查 Snowflake 配置与节点分配是否冲突。 - 调试技巧 - 开启 SQL 日志,观察实际执行的 SQL 与参数。 - 使用分页插件打印分页统计,验证查询范围。 - 针对慢查询使用 EXPLAIN 分析执行计划。 - 恢复策略 - 对高并发写入增加重试与退避。 - 对逻辑删除表进行定期清理与归档。 章节来源 - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) ## 结论 本数据访问层以 MyBatis Plus 为核心,通过统一的 CrmBaseMapper、完善的配置与扩展点(注入器、填充器、ID 生成器),实现了高效、可维护的数据访问能力。结合连接池、分页、乐观锁、逻辑删除等特性,以及 SQL 监控与调试手段,可在保证性能的同时提升开发效率与系统稳定性。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 最佳实践 - 实体字段命名规范与 MP 注解一致性。 - 分页查询必须包含合理排序与索引。 - 批量操作控制事务粒度,避免长事务。 - 敏感字段加密存储,审计字段自动填充。 - 参考路径 - 配置入口:MybatisPlusConfig - 自定义 SQL:CrmSqlInjector - 自动填充:MetaObjectFillHandler - ID 生成:CustomIdGenerator + SnowflakeIdWorker - 实体基类:BaseEntity / OwnedEntity - 基础服务:BaseServiceImpl / IBaseService [本节为补充说明,不直接分析具体文件]