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

数据访问层

**本文引用的文件** - [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。

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

[本节为补充说明,不直接分析具体文件]