# 数据访问架构
**本文引用的文件**
- [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注入;敏感数据脱敏与加密存储
[本节为补充说明,不直接分析具体文件]