# 数据访问架构 **本文引用的文件** - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.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) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.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) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [AuthUserMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthUserMapper.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向数据层开发者,系统化阐述CRM系统基于MyBatis-Plus的ORM数据访问架构与最佳实践。内容覆盖: - 通用Mapper基类与Service抽象的设计与使用 - 分页查询、批量插入、主键生成、自动填充等能力 - 数据库连接池配置、事务管理策略、SQL注入防护 - 实体设计规范、字段映射规则、关联查询处理 - 数据访问层次结构与优化策略 ## 项目结构 本项目采用多模块分层设计,数据访问相关代码集中在基础模块与业务模块中: - 基础模块(crm-base):提供通用Mapper、Service实现、MyBatis-Plus配置、安全与数据权限工具、统一结果与分页封装等 - 认证模块(crm-auth):具体业务实体、Mapper接口、Service实现示例 - 应用入口(crm-app):应用启动与全局配置 ```mermaid graph TB subgraph "应用层" APP["应用启动
crm-app"] end subgraph "业务模块" AUTH["认证模块
crm-auth"] end subgraph "基础模块" BASE["基础模块
crm-base"] end DB["数据库"] APP --> AUTH AUTH --> BASE BASE --> DB ``` **图表来源** - [application.yml](file://crm-app/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) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) ## 核心组件 - CrmBaseMapper:通用Mapper基类,扩展常用CRUD与分页能力,供业务Mapper继承 - BaseServiceImpl:通用Service实现,封装标准CRUD、分页查询、批量操作等 - IBaseService:通用Service接口定义,约束业务Service的统一方法集 - MybatisPlusConfig:MyBatis-Plus全局配置(分页插件、自动填充、主键策略、SQL注入拦截等) - MetaObjectFillHandler:自动填充处理器(创建时间、更新时间、创建人等) - CustomIdGenerator/SnowflakeIdWorker:分布式雪花ID生成器 - InsertBatchOnDuplicateKeyUpdate:批量插入去重更新策略 - BaseEntity/OwnedEntity:实体基类,统一审计字段与数据归属字段 - PageResult/PageConverter:分页结果封装与转换工具 - DataScope注解与DataScopeHelper/DataVisibilityContext/SecurityUtils:数据权限与可见性控制 **章节来源** - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.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) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.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) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) ## 架构总览 数据访问层遵循“Controller → Service → Mapper → MyBatis-Plus → 数据库”的分层模式,通过通用基类与配置实现标准化开发。 ```mermaid classDiagram class CrmBaseMapper { +通用CRUD方法() +分页查询() +批量操作() } class BaseServiceImpl { +新增() +修改() +删除() +查询单条() +分页查询() +批量保存() } class IBaseService { <> +新增() +修改() +删除() +查询单条() +分页查询() +批量保存() } class AuthUserMapper class SysDeptMapper class AuthUserServiceImpl class SysDeptServiceImpl AuthUserMapper --|> CrmBaseMapper : "继承" SysDeptMapper --|> CrmBaseMapper : "继承" AuthUserServiceImpl ..|> IBaseService : "实现" SysDeptServiceImpl ..|> IBaseService : "实现" BaseServiceImpl <|-- AuthUserServiceImpl : "复用" BaseServiceImpl <|-- SysDeptServiceImpl : "复用" ``` **图表来源** - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [AuthUserMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthUserMapper.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ## 详细组件分析 ### 通用Mapper基类:CrmBaseMapper - 职责:为所有业务Mapper提供统一的CRUD与分页能力,减少样板代码 - 关键能力: - 标准增删改查方法 - 分页查询支持(结合MyBatis-Plus分页插件) - 批量操作(如批量插入、批量更新) - 条件构造器友好扩展 - 使用方式:业务Mapper直接继承该基类,无需重复定义基础方法 **章节来源** - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) ### 通用Service实现:BaseServiceImpl - 职责:封装通用的Service逻辑,包括事务边界、参数校验、分页转换、异常处理等 - 关键能力: - 单条/批量新增、修改、删除 - 按主键查询与条件查询 - 分页查询(返回统一PageResult) - 与CrmBaseMapper协作完成数据访问 - 事务策略:在需要原子性的方法上声明事务,确保一致性 **章节来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) ### 分页查询实现 - 分页插件:通过MyBatis-Plus分页插件启用分页功能 - 分页对象:使用Page对象进行分页查询,返回结果转换为PageResult - 转换工具:PageConverter负责将框架分页对象转换为业务分页结果 ```mermaid sequenceDiagram participant Client as "调用方" participant Service as "BaseServiceImpl" participant Mapper as "CrmBaseMapper" participant MP as "MyBatis-Plus分页插件" participant DB as "数据库" Client->>Service : 请求分页查询 Service->>Service : 构建查询条件 Service->>MP : 创建分页对象并设置页码/大小 Service->>Mapper : 执行分页查询 Mapper->>MP : 拦截并改写SQL MP->>DB : 执行分页SQL DB-->>MP : 返回分页数据 MP-->>Mapper : 返回分页结果 Mapper-->>Service : 返回分页结果 Service->>Service : 转换为PageResult Service-->>Client : 返回分页响应 ``` **图表来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) **章节来源** - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) ### 主键生成与自动填充 - 主键策略:自定义雪花ID生成器,保证分布式环境下唯一性与有序性 - 自动填充:通过MetaObjectFillHandler在插入/更新时自动填充审计字段(如创建时间、更新时间、创建人等) ```mermaid flowchart TD Start(["实体持久化"]) --> CheckId{"是否已设置主键?"} CheckId --> |否| GenId["雪花ID生成器生成主键"] CheckId --> |是| FillAudit["自动填充审计字段"] GenId --> FillAudit FillAudit --> Save["写入数据库"] Save --> End(["完成"]) ``` **图表来源** - [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) - [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) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) ### 批量插入与冲突处理 - 批量插入:通过InsertBatchOnDuplicateKeyUpdate实现高效批量插入 - 冲突策略:根据业务需求配置“存在即更新”或忽略冲突,避免重复数据 **章节来源** - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) ### 实体设计规范与字段映射 - BaseEntity:统一审计字段(如id、createTime、updateTime、creator、updater等) - OwnedEntity:数据归属字段(如deptId、ownerId等),配合数据权限控制 - 字段映射:遵循MyBatis-Plus默认命名规则,必要时使用注解指定映射 ```mermaid erDiagram BASE_ENTITY { bigint id PK datetime create_time datetime update_time string creator string updater } OWNED_ENTITY { bigint dept_id bigint owner_id } BASE_ENTITY ||--o{ OWNED_ENTITY : "继承" ``` **图表来源** - [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) ### 数据权限与可见性控制 - DataScope注解:用于标记方法的数据范围 - DataScopeHelper:解析数据范围条件,动态拼接SQL - DataVisibilityContext:维护当前请求的数据可见性上下文 - SecurityUtils:获取当前登录用户信息,辅助权限判断 ```mermaid sequenceDiagram participant Controller as "控制器" participant Service as "业务Service" participant Helper as "DataScopeHelper" participant Context as "DataVisibilityContext" participant DB as "数据库" Controller->>Service : 调用带@DataScope的方法 Service->>Context : 读取当前用户可见范围 Service->>Helper : 解析数据范围条件 Helper-->>Service : 返回WHERE条件片段 Service->>DB : 执行带数据范围的查询 DB-->>Service : 返回受限数据 Service-->>Controller : 返回结果 ``` **图表来源** - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) **章节来源** - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) ### 业务Mapper与Service示例 - AuthUserMapper/SysDeptMapper:继承CrmBaseMapper,获得通用CRUD能力 - AuthUserServiceImpl/SysDeptServiceImpl:继承BaseServiceImpl,复用通用Service逻辑 **章节来源** - [AuthUserMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthUserMapper.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ## 依赖关系分析 - MyBatis-Plus:提供ORM能力、分页插件、自动填充、主键策略等 - 数据源与连接池:由Spring Boot自动装配,可通过配置文件调整连接池参数 - 安全与权限:SecurityUtils与DataScope相关组件协同工作,保障数据安全 ```mermaid graph TB MP["MyBatis-Plus"] --> Config["MybatisPlusConfig"] Config --> Fill["MetaObjectFillHandler"] Config --> IdGen["CustomIdGenerator"] Config --> Batch["InsertBatchOnDuplicateKeyUpdate"] Base["BaseServiceImpl"] --> Mapper["CrmBaseMapper"] Mapper --> MP Security["SecurityUtils"] --> Scope["DataScopeHelper"] Scope --> Context["DataVisibilityContext"] ``` **图表来源** - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.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) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) **章节来源** - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) ## 性能考虑 - 分页查询:优先使用分页插件,避免全量加载;合理设置页大小 - 批量操作:使用批量插入/更新接口,减少网络往返 - 索引优化:为高频查询字段建立合适索引,避免全表扫描 - SQL监控:开启SQL日志与慢查询分析,定位性能瓶颈 - 连接池调优:根据并发与负载调整连接池大小、超时与回收策略 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 分页无效:检查分页插件是否注册、请求参数是否正确 - 自动填充未生效:确认MetaObjectFillHandler已配置且字段匹配 - 主键重复:检查雪花ID生成器配置与节点ID分配 - 数据权限异常:查看DataScope注解与方法签名、上下文是否正确设置 - 事务不回滚:确认异常类型与事务传播行为是否符合预期 **章节来源** - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.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) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) ## 结论 通过CrmBaseMapper与BaseServiceImpl的抽象设计,结合MyBatis-Plus的强大能力,CRM系统在数据访问层实现了高度标准化与可复用。配合数据权限、自动填充、批量操作与分页机制,开发者可以专注于业务逻辑,提升开发与维护效率。建议严格遵循实体规范、合理使用索引与事务,持续优化SQL与连接池配置,以保障系统稳定与高性能。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 实体设计建议:统一继承BaseEntity/OwnedEntity,明确字段语义与映射规则 - 查询优化建议:优先使用条件构造器,避免N+1查询,合理使用JOIN与子查询 - 事务管理建议:在Service层声明事务,明确边界与传播行为 - 安全与合规:始终使用参数化查询,防止SQL注入;敏感数据脱敏与加密存储 [本节为补充说明,不直接分析具体文件]