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