加1=1是为了避免动态拼接SQL时出现“WHERE AND...”语法错误,它作为恒真条件占位,使所有后续条件统一用AND连接,简化逻辑;但现代ORM如MyBatis的标签可自动处理,手写时应优先用参数化查询与条件列表拼接。

为什么动态拼接 SQL 时总要加 1=1
因为不加就容易拼出语法错误的 SQL,比如 WHERE AND name = 'Tom' —— AND 直接跟在 WHERE 后面是非法的。加个 1=1 就相当于先占个位置,后面所有条件统一用 AND 连接,不用每次判断“这是不是第一个条件”。
MyBatis 等框架里早就不靠 1=1 了
现代 ORM 或模板引擎(如 MyBatis 的 <where></where> 标签)会自动处理开头和结尾的 AND/OR。它只在有子条件时才插入 WHERE,还会智能删掉开头多余的 AND。
-
<where></where>标签内部的AND不用管位置,框架自动清理 - 如果所有
<if></if>都不满足,整个<where></where>块会被跳过,生成纯SELECT * FROM t - 手写
1=1在这种场景下纯属冗余,还可能干扰日志排查和执行计划
1=1 在数据库层真不影响性能吗
理论上优化器会消除它,但实际并非完全无代价:
- MySQL 8.0+、PostgreSQL 等主流引擎确实常忽略
1=1,执行计划和纯WHERE col = ?一致 - 但某些旧版本或特定配置下(如关闭了常量折叠优化),它仍会参与谓词分析流程
- 更关键的是:它会让慢查询日志、APM 工具里的 SQL 看起来可疑——运维看到
WHERE 1=1 AND ...第一反应是“这 SQL 是拼出来的?有没有注入?” - 当语句带
JOIN+GROUP BY+ 多层嵌套时,1=1会进一步降低可读性,调试成本上升
如果不用 1=1,字符串拼接怎么写才安全
真要手拼(比如 JDBC 原生调用、脚本导出等场景),推荐用“条件收集 + join”模式,而不是硬塞 1=1:
- 用列表存条件片段:
conditions.add("name = ?"),最后String.join(" AND ", conditions) - 拼完整 SQL 时,只在
conditions非空时才加WHERE关键字 - 永远用参数化查询(
?占位符),别把变量直接拼进字符串——这点比1=1存不存在重要得多 - 如果必须兼容空条件且不想改结构,可用
WHERE true替代1=1,语义更清晰,部分数据库也认
真正该警惕的不是 1=1 本身,而是它背后暴露的代码习惯:条件逻辑没抽象、SQL 构建缺乏边界检查、参数未隔离。这些地方出问题,远比多一个恒真表达式严重得多。

















