MyBatisPlus中MPJ联表查询坑

如果在表映射对象中使用@TableLogic,MyBatisPlus 会在查询时自动添加del = 0,但是在关联表查询时会出现问题。

比较

select a.* from A a
left join B b on b.id = a.b_id
where a.del = 0 and b.del = 0;
  • 连接条件:仅基于 b.id = a.b_id,不限制 b.del。
  • 过滤位置:在 WHERE 子句中对 b.del = 0 进行过滤。
  • 执行逻辑:
    • 先执行 LEFT JOIN,生成所有 A 的行,若 B 无匹配则 b 列全为 NULL。
    • 随后 WHERE 条件 b.del = 0 会剔除所有 b.del 为 NULL(未匹配)或 b.del ≠ 0(匹配但不符合)的行。

结果:只返回 A 中在 B 有匹配且 b.del = 0 的行。
由于 LEFT JOIN 被 WHERE 条件“消灭”了未匹配的行,实际效果等价于INNER JOIN

select a.* from A a
left join B b on (b.id = a.b_id and b.del = 0)
where a.del = 0;
  • 连接条件:将 b.del = 0 直接放在 ON 子句中,与 id 匹配共同构成连接条件。
  • 过滤位置:WHERE 仅过滤 a.del = 0,不限制 b 的列。
  • 执行逻辑:
    • LEFT JOIN 根据完整连接条件(id 相等 且 b.del = 0)尝试匹配 B。
    • 如果某行 A 在 B 中没有满足该条件的记录(包括 B 无匹配、或匹配但 b.del ≠ 0),则 b 列全部为 NULL,但该 A 行仍会保留。
  • 最终 WHERE a.del = 0 仅过滤 A 的行。

结果:返回 所有满足 a.del = 0 的 A 行,对于其中有匹配且 b.del = 0 的行,B 列有值;否则 B 列为 NULL。

结论

因此在使用MPJLambdaWrapper时需要手动增加del条件,并使用
MPJLambdaWrapper.disableSubLogicDel()

posted @ 2026-07-16 10:17  Joeyin  阅读(9)  评论(0)    收藏  举报