面试tips--MyBatis--<where> where 1=1 的区别
1. 两种写法的背景
在动态 SQL 中,经常需要根据条件拼接
WHERE
子句:
如果直接拼接,容易出现 多余的 AND / OR 或者 空 WHERE 的情况。
为了解决这个问题,有两种常见做法:
方式一:写
WHERE 1=1
,后续条件都用 AND 拼接。方式二:使用 MyBatis 的
<where>
标签,它会自动处理 WHERE 和 AND。
2.
<where>
的特点
<where>
会自动在拼接的第一个条件前加上WHERE
。如果条件前面有多余的
AND
或OR
,会自动去掉。如果没有条件,则不会生成
WHERE
。✅ 示例:
<select id="queryUser" resultType="User">SELECT * FROM user<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where> </select>
如果
name = 'Tom'
,age = null
,生成 SQL 为:SELECT * FROM user WHERE name = 'Tom';
如果两个条件都为空:
SELECT * FROM user;
3.
where 1=1
的特点
WHERE 1=1
永远成立,相当于一个 假条件占位符。后续条件就可以直接拼接
AND
,避免多余的逻辑判断。✅ 示例:
<select id="queryUser" resultType="User">SELECT * FROM userWHERE 1=1<if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if> </select>
如果
name = 'Tom'
,age = null
,生成 SQL 为:SELECT * FROM user WHERE 1=1 AND name = 'Tom';
如果条件都为空:
SELECT * FROM user WHERE 1=1;
4. 为什么不推荐
where 1=1
语义不清晰:多了一个永远为真的条件,看上去比较“脏”。
可能影响优化器(MySQL 5.7 以前):
MySQL 在 5.7 以前的优化器,对
WHERE 1=1
可能无法完全优化掉,会导致 执行计划不够简洁。例如
EXPLAIN
时,可能仍会保留1=1
,对复杂 SQL 可能造成 额外开销。可维护性差:别人看 SQL 时会疑惑为什么写一个无意义的条件。
5. MySQL 版本差异
MySQL 5.6 及以前:
WHERE 1=1
有可能被保留在执行计划中(虽然性能影响一般不大,但在高并发复杂查询下可能有影响)。因此很多人建议避免这种写法,改用
<where>
。MySQL 5.7 及以后:
优化器对
WHERE 1=1
能 完全优化掉,执行计划不会受影响。性能几乎等同于
<where>
,所以从性能角度讲已经没问题。
6. 总结
推荐写法:使用 MyBatis 的
<where>
,因为:
自动处理条件拼接,避免 SQL 脏乱。
不需要担心 MySQL 版本的差异。
WHERE 1=1
的问题:
在 MySQL 5.6 及以前,优化器可能无法完全消除,导致执行计划里有多余条件。
在 MySQL 5.7+ 已经优化掉了,性能没问题,但语义和可维护性仍不如
<where>
。👉 结论:从语义和维护角度出发,优先用
<where>
,即使在 5.7+ 版本中。