2026-10-18 06:18:13
WHERE 1=1 是一种在动态 SQL 查询中常用的技巧,主要用于简化条件拼接逻辑,避免因首个条件为空导致的语法错误。
核心作用简化动态条件拼接在 MyBatis 等框架中,当需要根据参数动态生成 WHERE 子句时,若首个条件可能为空,直接拼接 AND 会导致 SQL 语法错误(如 WHERE AND title=...)。而 WHERE 1=1 作为恒真条件,可确保后续条件直接通过 AND 连接,无需额外判断是否为首个条件。
示例代码解析
<select id="queryBookInfo" parameterType="com.ths.platform.entity.BookInfo" resultType="java.lang.Integer"> select count(id) from t_book t where 1=1 <if test="title !=null and title !='' "> AND title = #{title} </if> <if test="author !=null and author !='' "> AND author = #{author} </if> </select>若 title 和 author 均不为空,生成的 SQL 为:WHERE 1=1 AND title=? AND author=?
若 title 为空,则跳过该条件,生成的 SQL 为:WHERE 1=1 AND author=?
恒真条件 1=1 始终成立,不影响查询结果。
索引使用情况
实测结论:WHERE 1=1 不会导致索引失效。通过 EXPLAIN 分析,MySQL 优化器会直接忽略 1=1,实际执行的 SQL 等价于 WHERE title=?,仍会使用索引。
关键证据:
EXPLAIN SELECT * FROM t_book WHERE title = "且在人间";EXPLAIN SELECT * FROM t_book WHERE 1=1 AND title = "且在人间";两次查询的 possible_keys 和 key 字段均显示使用了索引。潜在问题
优化器开销:虽然 1=1 会被优化掉,但解析过程仍需微小开销。在数据量极大或高频查询场景下,可能累积成性能瓶颈。
代码可读性:恒真条件可能让其他开发者困惑,需通过注释说明意图。
推荐优化方案使用 MyBatis 的 <where> 标签替代 WHERE 1=1,该标签会自动处理条件前的 AND/OR,并智能省略多余的连接词:
<select id="queryBookInfo" parameterType="com.ths.platform.entity.BookInfo" resultType="java.lang.Integer"> select count(*) from t_book t <where> <if test="title !=null and title !='' "> title = #{title} </if> <if test="author !=null and author !='' "> AND author = #{author} </if> </where> </select>优势:生成的 SQL 更简洁(如 WHERE title=? AND author=?),避免恒真条件,同时保持动态条件的灵活性。