QueryWrapper 单表一时爽,多表火葬场 一款“好用”的工具MyBatis-Plus 的 QueryWrapper 在国内非常普及。单表场景下它确实好用wrapper.eq(name,张三).ge(age,18).orderByDesc(create_time);没有 SQL 字符串没有字段硬编码IDE 自动补全链式调用看着很优雅。这个场景下它确实没问题。边界在哪里一旦你的查询涉及多张表QueryWrapper 的边界就开始暴露。联表查询你要查“订单金额大于 100 的用户”SQL 很简单SELECT*FROMuserWHEREidIN(SELECTuser_idFROMorderWHEREamount100)QueryWrapper 怎么写wrapper.inSql(id,SELECT user_id FROM order WHERE amount 100)你已经退回原生 SQL 了。之前那些链式调用、类型安全、IDE 补全这个场景下全部作废。标量子查询、半连接、派生查询、窗口函数——这些 SQL 的常规能力QueryWrapper 一个都不支持。不是“写起来不方便”是“根本没有对应的 API”。单表条件只是特例联表才是常态企业开发的核心是多表联动权限要查角色表关联用户表报表要 GROUP BY 多表 JOIN业务流程要跨表查状态。单表场景不到 10%多表才是 90%。如果条件层设计成“只服务于单表”那你 90% 的业务场景都在框架的边界之外。既然要破就要立如果条件层设计成“主表和关联表统一”会是什么样publicclassOrderCondextendsBaseCondition{privateStringorderNo;privateIntegerorderStatus;privateStringuserName;// 关联表字段privateStringuserPhone;// 关联表字段privateObject[]orderNos;OverrideprotectedvoidaddCondition(){// 主表条件——用 and()and(order_no LIKE,orderNo,3);and(order_status ,orderStatus);in(order_no,orderNos);// 关联表条件——用 add()自己写别名add(AND u.name LIKE ?,userName,3);add(AND u.phone ?,userPhone);}}注意主表和关联表的条件在同一个addCondition()方法里用同一套 API同一个参数收集机制。没有什么“Wrapper 只认主表”的限制也没有什么“联表要换另一种写法”的割裂。这个OrderCond可以同时服务于单表查询和 15 张表的联查条件完全复用。这才是条件层该有的样子它不关心你是几张表它只关心“这个条件要不要加”。开源地址核心框架https://gitee.com/gao_zhenzhong/simple-dao系统底座https://gitee.com/gao_zhenzhong/simple-dao-starter代码生成器https://gitee.com/gao_zhenzhong/simple-dao-coder实战案例https://gitee.com/gao_zhenzhong/simple-dao-demo