eladmin-mp源码深度剖析:MyBatis-Plus自动填充、分页插件与SQL监控扩展点
eladmin-mp源码深度剖析:MyBatis-Plus自动填充、分页插件与SQL监控扩展点
eladmin-mp 是基于 Spring Boot 2.7.18、MyBatis-Plus、Spring Security、Redis 与 Vue 的前后端分离后台管理系统,权限控制采用 RBAC,自带代码生成与动态路由。本文带你深度剖析 eladmin-mp 数据访问层最具代表性的三大扩展点:MyBatis-Plus 自动填充、分页插件与 p6spy SQL 监控,一步步看懂这套脚手架高效、优雅的数据层设计。
快速认识 eladmin-mp:数据层配置藏在哪里 🗂️
eladmin-mp 将代码按职责拆分为多个 Maven 模块,所有与 MyBatis-Plus 相关的通用配置都集中在公共模块 eladmin-common 的 config/mybatis 目录下,这里就是本文的主角们:
eladmin-common:公共模块,承载 mybatis、redis、web 等通用配置与工具类eladmin-system:核心业务模块(系统管理、运维部署、定时任务、安全认证)eladmin-logging:操作日志模块eladmin-tools:工具模块(邮件、支付宝、本地存储、S3 存储)eladmin-generator:前后端代码生成器
项目在根 pom.xml 中引入 mybatis-plus-boot-starter 3.5.3.1,配合 p6spy 3.9.1 实现 SQL 监控,为后续三个扩展点提供了完整的依赖底座。
扩展点一:MyBatis-Plus 自动填充,让创建人/创建时间"自动长出来" ⏱️
传统开发中,每张表都要手工维护 createBy、createTime、updateBy、updateTime 四个字段,繁琐且容易遗漏。eladmin-mp 用"注解标记 + 处理器填充"两步彻底解决这个问题。
第一步:BaseEntity 用注解声明填充时机
所有实体继承 me.zhengjie.base.BaseEntity,公共字段上通过 @TableField(fill = ...) 声明填充时机,源码位于 eladmin/eladmin-common/src/main/java/me/zhengjie/base/BaseEntity.java:
createTime、createBy标记为FieldFill.INSERT(仅插入时填充)updateTime、updateBy标记为FieldFill.INSERT_UPDATE(插入与更新都填充)
第二步:MyMetaObjectHandler 实现真正的填充逻辑
MyMetaObjectHandler 实现了 MyBatis-Plus 的 MetaObjectHandler 接口,在插入和更新两个生命周期中自动写入字段值,核心代码位于 eladmin/eladmin-common/src/main/java/me/zhengjie/config/mybatis/MyMetaObjectHandler.java:
this.strictInsertFill(metaObject, "createTime", Timestamp.class, DateTime.now().toTimestamp());
this.strictInsertFill(metaObject, "createBy", String.class, username);
这里有两个值得学习的细节:
- 操作人自动识别:通过
SecurityUtils.getCurrentUsername()获取当前登录用户,配合try-catch兜底为System,既优雅又健壮 - strict 系列方法:
strictInsertFill/strictUpdateFill只有在字段值非空或已声明填充时才会生效,避免覆盖业务传入的值
自动填充的完整行为可以用一张表概括:
| 操作场景 | 自动填充字段 | 处理器方法 |
|---|---|---|
| 新增数据 | createTime、updateTime、createBy、updateBy | insertFill |
| 更新数据 | updateTime、updateBy | updateFill |
| 查询数据 | 无 | — |
扩展点二:MyBatis-Plus 分页插件,一页数据背后的拦截器魔法 📄
eladmin-mp 的分页基于 MyBatis-Plus 3.5.x 推荐的 MybatisPlusInterceptor 拦截器链实现,配置极简却功能强大。
两行代码注册分页拦截器
eladmin/eladmin-common/src/main/java/me/zhengjie/config/mybatis/MybatisPlusConfig.java 中,通过一个 @Bean 完成拦截器注册:
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
PaginationInnerInterceptor 会在执行 SQL 前自动改写为 LIMIT 分页语句,并自动发起一次 COUNT 查询统计总条数,开发者完全不需要手写分页 SQL。
从 Controller 到 Mapper 的分页落地流程
分页在 eladmin-mp 中的完整调用链非常清晰,以运维模块 maint 为例:
- Controller 层构造分页参数:
new Page<>(criteria.getPage(), criteria.getSize()),示例见eladmin/eladmin-system/src/main/java/me/zhengjie/modules/maint/rest/AppController.java - Mapper 层接收分页对象并返回分页结果:
IPage<App> queryAll(@Param("criteria") AppQueryCriteria criteria, Page<Object> page) - Service 层统一转成前端友好的结构:
PageUtil.toPage(page)返回PageResult<T>
其中 PageUtil(eladmin/eladmin-common/src/main/java/me/zhengjie/utils/PageUtil.java)与 PageResult(eladmin/eladmin-common/src/main/java/me/zhengjie/utils/PageResult.java)是分页结果的标准封装,前者负责把 IPage 转换为 PageResult,后者只暴露 content(数据列表)与 totalElements(总条数)两个字段,接口返回结构高度统一。
扩展点三:p6spy SQL 监控,每条 SQL 的耗时都逃不过你的眼睛 🔍
性能排查的第一步是"看得见 SQL"。eladmin-mp 集成 p6spy 实现完整的 SQL 监控与慢 SQL 分析,整个过程只需三步。
三步开启 p6spy SQL 监控
- 引入依赖:根
pom.xml中加入p6spy 3.9.1 - 替换数据源驱动:在
eladmin/eladmin-system/src/main/resources/config/application-dev.yml中,把driverClassName换成com.p6spy.engine.spy.P6SpyDriver,url前缀改为jdbc:p6spy:mysql://... - 编写 spy 配置:
eladmin/eladmin-system/src/main/resources/spy.properties中启用MybatisPlusLogFactory,并将日志格式指向自定义类
CustomP6SpyLogger:带颜色的 SQL 日志
默认的 p6spy 日志又长又乱,eladmin-mp 通过实现 MessageFormattingStrategy 接口自定义输出格式,源码位于 eladmin/eladmin-common/src/main/java/me/zhengjie/config/mybatis/CustomP6SpyLogger.java,核心逻辑只有两步:
- 用正则把 SQL 中的换行与多余空格压缩成单行,日志更紧凑
- 拼接成
sql- 时间 [Time: xxms] - SQL语句的格式,并用 ANSI 颜色标记时间与耗时,终端里一眼就能分辨
最终控制台输出效果类似:
sql- 2026-08-17 09:06:42 [Time: 12ms] - SELECT * FROM sys_user WHERE user_id = 1;
排查慢 SQL 时,只看 Time 字段就能快速定位瓶颈,比打开数据库慢查询日志高效得多。
三个扩展点如何协同工作 🤝
这三个扩展点在数据访问链路中各司其职、层层配合:
- 请求进入 Service 后,分页插件负责将普通查询自动改写为带
LIMIT与COUNT的分页 SQL - SQL 真正执行前,自动填充处理器为实体补全操作人与时间字段,保证审计信息完整
- SQL 执行完成后,p6spy 监控立刻打印出格式化 SQL 与耗时,供开发者实时观察
三者叠加,让 eladmin-mp 在"增删改查"这件看似平凡的事情上做到了自动化、可观测、易排查。
实战建议:如何基于这三个扩展点二次开发 💡
理解了原理,二次开发就游刃有余:
- 想加租户隔离:在
MyMetaObjectHandler中增加一个tenantId字段的自动填充即可 - 想限制单次分页大小:
PaginationInnerInterceptor支持设置maxLimit,防止恶意大分页拖垮数据库 - 想按慢 SQL 阈值告警:在
CustomP6SpyLogger中判断elapsed参数,超过阈值时输出告警日志
小结
eladmin-mp 用 MyMetaObjectHandler、MybatisPlusConfig、CustomP6SpyLogger 三个类,就把自动填充、分页插件、SQL 监控三大扩展点讲得明明白白——这正是它"开箱即用、易于改造"的底气所在。想亲自跑起来验证这套设计,可以克隆仓库 https://gitcode.com/gh_mirrors/el/eladmin-mp 后启动 eladmin-system 模块,配合前端 eladmin-web 一起体验。
更多推荐

所有评论(0)