# 服务层封装 **本文引用的文件** - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.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) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.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) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) ## 更新摘要 **所做更改** - 更新了事务管理章节,详细说明新增的@Transactional注解应用 - 增强了SysRoleServiceImpl和AuthUserServiceImpl的事务安全说明 - 完善了多表操作的事务一致性保障机制 - 更新了实际使用示例中的事务处理最佳实践 ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向CRM后端项目的服务层封装,聚焦于通用服务抽象与实现:IBaseService接口设计与BaseServiceImpl通用实现。内容涵盖CRUD、分页查询、批量操作、事务管理、数据权限与审计填充、以及扩展自定义服务的最佳实践与示例。目标是帮助开发者快速理解并复用基础服务能力,提升开发效率与代码一致性。 ## 项目结构 服务层封装位于基础模块crm-base中,提供统一的接口与实现;业务模块crm-auth通过继承该基础能力,构建具体领域服务(如部门、菜单、角色等)。 ```mermaid graph TB subgraph "基础模块 crm-base" IBase["IBaseService 接口"] BaseImpl["BaseServiceImpl 实现"] MPConf["MybatisPlusConfig 配置"] Fill["MetaObjectFillHandler 自动填充"] SQLI["CrmSqlInjector 注入器"] BE["BaseEntity 基础实体"] OE["OwnedEntity 数据归属实体"] PR["PageResult 分页结果"] R["Result 统一响应"] DSH["DataScopeHelper 数据权限助手"] SU["SecurityUtils 安全工具"] end subgraph "业务模块 crm-auth" ISysDept["ISysDeptService 接口"] SysDeptImpl["SysDeptServiceImpl 实现"] ISysRole["ISysRoleService 接口"] SysRoleImpl["SysRoleServiceImpl 实现"] IAuthUser["IAuthUserService 接口"] AuthUserImpl["AuthUserServiceImpl 实现"] end IBase --> BaseImpl BaseImpl --> MPConf BaseImpl --> Fill BaseImpl --> SQLI BaseImpl --> BE BaseImpl --> OE BaseImpl --> PR BaseImpl --> R BaseImpl --> DSH BaseImpl --> SU ISysDept --> SysDeptImpl SysDeptImpl --> IBase ISysRole --> SysRoleImpl SysRoleImpl --> IBase IAuthUser --> AuthUserImpl AuthUserImpl --> IBase ``` **图表来源** - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.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) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.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) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ## 核心组件 - IBaseService:定义通用服务契约,包括新增、修改、删除、按ID获取、条件查询、分页查询、批量插入/更新/删除等。 - BaseServiceImpl:基于MyBatis-Plus的通用实现,封装事务、数据权限、审计字段自动填充、分页转换、批量操作优化等。 - 相关支撑: - MybatisPlusConfig:注册分页插件、乐观锁、SQL注入器等。 - MetaObjectFillHandler:自动填充创建时间、更新时间、创建人、更新人等审计字段。 - CrmSqlInjector:注入公共SQL片段或方法(如数据权限过滤)。 - BaseEntity/OwenedEntity:实体基类,承载通用字段与数据归属信息。 - PageResult/Result:统一的分页与响应包装。 - DataScopeHelper/SecurityUtils:数据权限与安全上下文工具。 ## 架构总览 服务层采用"接口+基础实现"的抽象模式,业务服务仅需继承基础服务即可复用CRUD与分页能力,并通过自身接口暴露领域语义化方法。 ```mermaid classDiagram class IBaseService { +保存实体() +批量保存() +更新实体() +批量更新() +删除实体() +批量删除() +按ID查询() +条件查询() +分页查询() } class BaseServiceImpl { -mapper : 泛型Mapper -dataScopeHelper : DataScopeHelper -securityUtils : SecurityUtils +保存实体() +批量保存() +更新实体() +批量更新() +删除实体() +批量删除() +按ID查询() +条件查询() +分页查询() } class SysDeptServiceImpl { +部门树查询() +部门权限过滤() } class ISysDeptService { +部门树查询() +部门权限过滤() } class SysRoleServiceImpl { +assignMenus() @Transactional +deleteRoleCascade() @Transactional } class ISysRoleService { +assignMenus() +deleteRoleCascade() } class AuthUserServiceImpl { +assignDepts() @Transactional +assignRoles() @Transactional +pageUserList() +stats() } class IAuthUserService { +assignDepts() +assignRoles() +pageUserList() +stats() } IBaseService <|.. BaseServiceImpl ISysDeptService <|.. SysDeptServiceImpl BaseServiceImpl <|-- SysDeptServiceImpl ISysRoleService <|.. SysRoleServiceImpl BaseServiceImpl <|-- SysRoleServiceImpl IAuthUserService <|.. AuthUserServiceImpl BaseServiceImpl <|-- AuthUserServiceImpl ``` **图表来源** - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ## 详细组件分析 ### IBaseService 接口设计 - 目标:为所有领域服务提供一致的CRUD与分页能力,降低重复代码。 - 关键能力: - 单条与批量保存/更新/删除 - 按ID查询与条件查询 - 分页查询(支持排序、过滤) - 设计要点: - 使用泛型约束实体类型,确保类型安全 - 返回统一结果包装,便于上层处理 - 与数据权限、审计填充解耦,由实现类统一处理 **章节来源** - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) ### BaseServiceImpl 实现类 - 目标:基于MyBatis-Plus提供通用实现,屏蔽底层细节。 - 关键能力: - CRUD:调用Mapper进行持久化 - 分页:结合分页插件与PageResult封装 - 批量:分批提交,减少事务压力 - 事务:默认开启事务,异常回滚 - 数据权限:在查询时注入数据范围过滤 - 审计填充:自动设置创建/更新时间与人员信息 - 性能优化: - 批量操作使用分批写入 - 分页查询避免全表扫描,合理使用索引 - 条件查询优先使用精确匹配与范围查询 ```mermaid flowchart TD Start(["进入服务方法"]) --> CheckTxn{"是否已存在事务?"} CheckTxn --> |否| BeginTxn["开启新事务"] CheckTxn --> |是| UseExisting["复用现有事务"] BeginTxn --> Execute["执行数据库操作"] UseExisting --> Execute Execute --> Success{"操作成功?"} Success --> |是| Commit["提交事务"] Success --> |否| Rollback["回滚事务"] Commit --> End(["结束"]) Rollback --> End ``` **图表来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) **章节来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) ### 分页查询流程 - 入口:服务方法接收分页参数(页码、每页大小、排序字段) - 处理:构造QueryWrapper或Lambda条件,应用数据权限过滤 - 执行:调用分页插件执行查询,转换为PageResult - 输出:返回统一分页结果 ```mermaid sequenceDiagram participant Client as "调用方" participant Service as "BaseServiceImpl" participant MP as "MyBatis-Plus 分页插件" participant DB as "数据库" Client->>Service : 分页查询(参数) Service->>Service : 组装查询条件 Service->>Service : 应用数据权限过滤 Service->>MP : 执行分页查询 MP->>DB : 生成并执行SQL DB-->>MP : 返回记录集 MP-->>Service : 返回分页对象 Service->>Service : 转换为PageResult Service-->>Client : 返回分页结果 ``` **图表来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) **章节来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) ### 批量操作策略 - 批量插入/更新/删除:分批次提交,控制单次事务规模 - 适用场景:导入导出、初始化数据、定时任务 - 注意事项: - 合理设置批次大小,避免内存溢出与长事务 - 对大表操作建议异步化或分片处理 **章节来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) ### 事务管理与错误处理 - 默认事务:BaseServiceImpl的batchUpsert方法默认开启事务,异常自动回滚 - **增强事务安全**:业务服务中的多表操作已添加@Transactional注解确保事务一致性 - **关键事务方法**: - `SysRoleServiceImpl.assignMenus()`:角色菜单分配,先删后插保证一致性 - `SysRoleServiceImpl.deleteRoleCascade()`:级联删除角色及关联数据 - `AuthUserServiceImpl.assignDepts()`:用户部门分配,包含复杂校验逻辑 - `AuthUserServiceImpl.assignRoles()`:用户角色分配,先删后插保证一致性 - 嵌套事务:支持传播行为,外层失败整体回滚 - 错误处理:统一异常捕获,返回标准错误码与消息 **更新** 新增了针对多表操作的关键事务保护,确保数据一致性 **章节来源** - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ### 数据权限与审计填充 - 数据权限:通过DataScopeHelper注入WHERE条件,限制可见数据范围 - 审计填充:MetaObjectFillHandler自动填充创建/更新时间与人员信息 - 安全上下文:SecurityUtils获取当前登录用户信息 **章节来源** - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) ### 自定义服务扩展指南 - 步骤: 1. 定义领域服务接口(如ISysDeptService),继承IBaseService 2. 实现类(如SysDeptServiceImpl)继承BaseServiceImpl 3. 在实现类中编写领域特定方法,复用基础CRUD与分页能力 4. 对于涉及多表操作的复杂业务,使用@Transactional注解确保事务一致性 5. 如需自定义数据权限或审计逻辑,扩展MetaObjectFillHandler或DataScopeHelper - 示例:部门服务扩展了树形结构与权限过滤,角色和用户服务展示了事务性多表操作 **更新** 增加了事务注解的使用指导 **章节来源** - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ### 实际使用示例 - 新增部门:调用保存方法,自动填充审计字段 - 分页查询部门:传入页码、每页大小、排序字段,返回PageResult - 批量导入:分批插入,控制事务大小 - 删除部门:级联删除子节点,保证数据一致性 - **角色菜单分配**:使用assignMenus方法进行事务性的先删后插操作 - **用户角色分配**:使用assignRoles方法进行事务性的角色授权 - **用户部门管理**:使用assignDepts方法进行复杂的部门分配,包含完整的数据校验 **更新** 增加了事务性操作的示例说明 **章节来源** - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ## 依赖关系分析 - 服务层依赖MyBatis-Plus进行数据访问 - 依赖安全与数据权限工具进行上下文与过滤 - 依赖统一结果与分页模型进行响应封装 ```mermaid graph LR IBase["IBaseService"] --> BaseImpl["BaseServiceImpl"] BaseImpl --> MP["MyBatis-Plus"] BaseImpl --> DSH["DataScopeHelper"] BaseImpl --> SU["SecurityUtils"] BaseImpl --> PR["PageResult"] BaseImpl --> R["Result"] BaseImpl --> Fill["MetaObjectFillHandler"] BaseImpl --> SQLI["CrmSqlInjector"] SysRoleImpl --> BaseImpl AuthUserImpl --> BaseImpl SysDeptImpl --> BaseImpl ``` **图表来源** - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.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) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.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) ## 性能考量 - 分页查询:避免N+1问题,使用JOIN或批量加载 - 批量操作:合理批次大小,避免长事务与内存峰值 - 索引优化:为常用查询字段建立索引,减少全表扫描 - 缓存策略:热点数据可引入Redis缓存,减轻数据库压力 - 连接池:调整连接池大小与超时,避免资源耗尽 - **事务优化**:合理划分事务边界,避免长事务影响并发性能 ## 故障排查指南 - 常见问题: - 分页无效:检查分页插件是否正确注册 - 审计字段未填充:确认MetaObjectFillHandler生效 - 数据权限不生效:检查DataScopeHelper与上下文 - 批量操作失败:查看批次大小与事务边界 - **事务回滚问题**:检查@Transactional注解是否正确配置,确认rollbackFor设置 - 调试建议: - 启用SQL日志,观察生成的SQL语句 - 使用统一异常处理器定位错误原因 - 通过TraceId追踪请求链路 - **事务调试**:使用Spring事务管理器监控事务状态 **更新** 增加了事务相关的故障排查指导 **章节来源** - [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) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) ## 结论 服务层封装通过IBaseService与BaseServiceImpl提供了稳定、高效、可扩展的通用能力。业务服务只需关注领域逻辑,显著提升开发效率与代码质量。结合数据权限、审计填充与事务管理,形成完整的服务层解决方案。**特别地,通过对关键业务方法的@Transactional注解增强,确保了多表操作的数据一致性和系统可靠性**。 ## 附录 - 实体基类:BaseEntity、OwnedEntity - 统一响应:Result、PageResult - 配置项:MybatisPlusConfig、MetaObjectFillHandler、CrmSqlInjector - **事务注解**:@Transactional用于保证业务方法的事务一致性 **章节来源** - [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) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.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) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)