U45 MyBatis-Plus 增强实验
实验使用 Liberica JDK 21、Boot 4.0.9 BOM 管理的依赖组合:mybatis-plus-spring-boot4-starter 3.5.18.1(core/spring 3.5.18.1)、mybatis-plus-extension 3.5.18、mybatis-plus-jsqlparser 3.5.18(JSqlParser 5.4)、mybatis-spring 4.1.0、Connector/J 9.7.0;数据库为 DBngin 的本机 MySQL 8.4.7。主程序手动装配 MybatisSqlSessionFactoryBean(不启用 Boot 自动配置;自动配置条件回查 U22/U42)。
python3 labs/mybatis-plus-u45/run.pyrunner 离线使用 Maven 本地缓存并核对依赖版本清单;Java 子进程使用环境变量白名单并关闭外部 Spring 配置文件;实验仅操作独立 study_u45_* schema,结束时 DROP,归属标记前中断由 U45Cleanup 应急清理,失败运行不覆盖已有成功证据。运行需要本机 MySQL 监听 127.0.0.1:3306(默认 root 空密码,可用 U45_MYSQL_USER / U45_MYSQL_PASSWORD 传入凭据,不写证据)。
场景与观察(12 组,U45 前缀逐字回收):
| 场景 | 观察 |
|---|---|
| 数据源校验 | 独有 schema 建表并核验目标,外部 catalog 不可达 |
| CRUD 与租户补列 | @TableName/@TableId(AUTO) 插入回填 id;tenant_id 由租户插件补列(插件改写 SQL,不回填实体字段,需重读验证) |
| 条件构造 | LambdaQueryWrapper eq/likeRight 与 LambdaUpdateWrapper.set 各 1 行 |
| 分页 | count 只统计当前租户 5 行;maxLimit=2 把 pageSize=100 截断为 2 |
| 错误租户 | 切换租户后读 0 行,写入隔离到租户 2 |
| 原生 SQL 边界 | 手写 @Select 仍被租户插件改写追加租户条件;逻辑删除不保护手写 SQL(可见已删行);JdbcTemplate 绕开 MyBatis 链路看到全部 6 行 |
| 逻辑删除 | deleteById 转 UPDATE,物理行仍在表内,BaseMapper 查询自动过滤 |
| 乐观锁 | 两个独立会话读同一版本,先更新者胜,旧版本影响 0 行,重读后重试成功(同会话两次 select 会命中一级缓存返回同一实例,实验因此用两个会话) |
| 防全表更新 | BlockAttack 在租户之前时拦截无 where 的 update;放在租户之后则被租户条件"救场"放行 4 行(beforePrepare 阶段顺序效应) |
| 清理 | 仅 DROP 本次 study_u45_* schema |
资源:入口、POM、实验主程序、实体、Mapper、应急清理、MySQL 证据。
边界:未运行多数据源、DataPermission/动态表名/illegal-sql 等其余插件、自定义 SqlInjector、IdType 分布式主键、生产容量与 Cluster;插件顺序的 count 行为以官方文档为准,本实验仅断言 BlockAttack 与租户的先后效应。