Skip to content

数据访问层架构

**本文引用的文件** - [DeviceMainMapper.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-device/lemes-service-dm-device-server/src/main/java/com/lenovo/lemes/service/dm/device/mapper/DeviceMainMapper.java) - [FactoryDo.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-common/lemes-service-dm-common-common/src/main/java/com/lenovo/lemes/service/dm/common/client/entity/FactoryDo.java) - [BaseEntity.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-common/lemes-service-dm-common-common/src/main/java/com/lenovo/lemes/service/dm/common/client/tools/entity/BaseEntity.java) - [Page.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-common/lemes-service-dm-common-common/src/main/java/com/lenovo/lemes/service/dm/common/client/tools/entity/Page.java) - [DataBaseAdapter.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/adapter/DataBaseAdapter.java) - [OpenApiFrameworkMapper.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/mapper/OpenApiFrameworkMapper.java) - [DynamicDbName.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/constants/DynamicDbName.java) - [Execution.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/api/entity/Execution.java) - [RequestParam.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/api/entity/RequestParam.java) - [OpenApi.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/api/entity/OpenApi.java) - [FrameworkController.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/api/FrameworkController.java) - [OpenApiController.java](file://lemes-cloud/lemes-framework/lemes-framework-datasource/src/main/java/com/lenovo/lemes/datasource/api/OpenApiController.java) - [DeviceMainDo.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-device/lemes-service-dm-device-server/src/main/java/com/lenovo/lemes/service/dm/device/client/entity/inner/DeviceMainDo.java) - [DeviceMainVo.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-device/lemes-service-dm-device-server/src/main/java/com/lenovo/lemes/service/dm/device/client/entity/outer/DeviceMainVo.java) - [DeviceMainQuery.java](file://lemes-cloud/lemes-business-devicemate/lemes-service-dm-device/lemes-service-dm-device-server/src/main/java/com/lenovo/lemes/service/dm/device/client/entity/query/DeviceMainQuery.java)

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本文件面向后端开发人员,系统化梳理 DeviceMate 项目的“数据访问层”架构与实现要点,重点覆盖以下方面:

  • MyBatis Plus 在项目中的应用:实体类设计、Mapper 接口定义、XML 映射文件组织思路
  • DAO 模式实现:通用 Mapper 基类、CRUD 标准实现、复杂查询封装策略
  • 动态数据源切换:多租户数据隔离、工厂切换逻辑、数据源配置管理
  • 分页查询:Page 对象使用、查询条件封装、排序与过滤逻辑
  • 批量操作:批量插入、批量更新、批量删除的性能优化
  • 最佳实践:SQL 注入防护、参数绑定、结果集映射

项目结构

DeviceMate 的数据访问层主要分布在业务服务模块与框架模块中:

  • 业务模块(lemes-service-dm-*):包含各业务域的实体类、Mapper 接口与查询对象
  • 框架模块(lemes-framework-datasource):提供动态数据源适配器、开放接口与执行模型

核心组件

  • 实体类与基类
    • 基类 BaseEntity:统一字段与审计信息,支撑所有业务实体
    • 具体实体如 FactoryDo:通过注解映射到数据库表,定义业务字段
  • 查询对象与视图对象
    • DeviceMainQuery:查询条件封装
    • DeviceMainVo:对外展示的视图对象
  • Mapper 接口
    • DeviceMainMapper:继承 MyBatis Plus 的 BaseMapper,扩展分页与非分页查询方法
  • 分页工具
    • Page:封装分页参数,供查询接口使用

章节来源

架构总览

下图展示了数据访问层的关键交互:控制器调用服务层,服务层通过 Mapper 访问数据库;动态数据源框架负责根据上下文选择目标数据源。

图表来源

详细组件分析

组件一:实体类与基类设计

  • BaseEntity:统一主键、创建时间、更新时间等字段,便于审计与一致性管理
  • FactoryDo:继承 BaseEntity,通过注解映射到 sys_factory 表,包含工厂编码、名称、简称、描述等字段
  • 设计原则
    • 字段命名与数据库保持一致,减少映射歧义
    • 使用 Lombok 简化样板代码,提升可维护性
    • 通过注解声明表名与字段映射,避免 XML 配置冗余

图表来源

章节来源

组件二:Mapper 接口与 CRUD 封装

  • DeviceMainMapper:继承 MyBatis Plus 的 BaseMapper,天然具备标准 CRUD 能力
  • 自定义方法
    • queryList(Page, DeviceMainQuery):支持分页查询,返回 IPage<DeviceMainVo>
    • queryList(DeviceMainQuery):支持非分页查询,返回 List<DeviceMainVo>
  • 设计要点
    • 使用 @Param 注解明确参数名,避免 XML 中的混淆
    • 返回类型采用 VO,隐藏内部 DO 映射细节,降低耦合

图表来源

章节来源

组件三:动态数据源切换与多租户隔离

  • 数据源适配器:通过适配器模式对接不同数据源,屏蔽底层差异
  • 执行模型:以 Execution 为核心承载执行上下文,包含请求参数、执行类型等
  • 参数模型:RequestParam 定义参数规则,OpenApi 定义开放接口元信息
  • 切换逻辑:结合 DynamicDbName 常量与上下文,选择目标数据源实例

图表来源

章节来源

组件四:分页查询实现

  • Page 对象:封装页码、每页条数等分页参数
  • Mapper 方法:queryList(Page, Query) 返回 IPage<T>,自动填充总记录数与分页信息
  • 查询条件:DeviceMainQuery 封装筛选字段,Mapper 层通过 @Param 传递
  • 排序与过滤:建议在查询对象中显式定义排序字段与过滤规则,避免硬编码

图表来源

章节来源

组件五:批量操作优化策略

  • 批量插入:Mapper 提供 insertBatchSomeColumn,按需传入列集合,减少无效字段写入
  • 批量更新:updateBatchById,支持批量 ID 更新,避免逐条事务开销
  • 批量删除:deleteBatchIds,一次性删除多个 ID
  • 性能建议
    • 控制单批次大小,避免内存压力
    • 合理设置超时与重试策略
    • 使用事务包裹,保证一致性

章节来源

组件六:最佳实践

  • SQL 注入防护
    • 使用 MyBatis Plus 内置的安全参数绑定,避免字符串拼接
    • 查询条件统一通过 @Param 传参,避免原生 SQL 直接拼接
  • 参数绑定
    • 查询对象与分页对象作为参数传递,保持接口清晰
    • 对外 VO 与内部 DO 解耦,避免直接暴露持久化字段
  • 结果集映射
    • Mapper 返回 VO,由上层统一装配,降低映射复杂度
    • 实体类字段与表字段一一对应,减少不必要的转换

章节来源

依赖分析

  • 组件内聚与耦合
    • Mapper 仅依赖实体类与查询对象,内聚性高
    • 动态数据源框架通过适配器与执行模型解耦具体数据源
  • 外部依赖
    • MyBatis Plus:提供通用 CRUD 与分页能力
    • Spring 注解:@Mapper、@Repository、@Param 等

图表来源

章节来源

性能考虑

  • 分页查询
    • 合理设置每页大小,避免过大数据量导致内存压力
    • 对高频查询建立必要索引,减少排序与过滤成本
  • 批量操作
    • 控制批次大小,结合数据库连接池参数优化吞吐
    • 使用事务批处理,减少往返次数
  • 动态数据源
    • 缓存数据源路由决策,降低频繁切换带来的开销
    • 对热点数据源进行连接池复用与预热

故障排查指南

  • 常见问题
    • 分页结果为空:检查 Page 参数是否正确传入,确认查询条件是否过于严格
    • 动态数据源未生效:核对上下文设置与适配器路由逻辑
    • SQL 注入风险:确保所有外部输入通过参数绑定传入,不拼接原生 SQL
  • 排查步骤
    • 打印 Mapper 调用链路与参数
    • 校验实体类注解与表结构一致性
    • 检查动态数据源的执行模型与参数规则

章节来源

结论

DeviceMate 的数据访问层以 MyBatis Plus 为基础,结合动态数据源框架实现了灵活的多租户隔离与高效的查询封装。通过统一的实体基类、清晰的查询对象与 VO 返回、以及完善的分页与批量操作策略,整体架构具备良好的可维护性与扩展性。建议在后续迭代中持续完善索引策略、连接池配置与监控告警,进一步提升性能与稳定性。

附录

  • 关键文件清单
    • 实体与基类:FactoryDo、BaseEntity
    • 查询与视图:DeviceMainQuery、DeviceMainVo、DeviceMainDo
    • Mapper:DeviceMainMapper
    • 分页工具:Page
    • 动态数据源:OpenApiFrameworkMapper、Execution、RequestParam、OpenApi、DynamicDbName、DataBaseAdapter