开发过程中动态 SQL 中where 1=1的作用是什么

在这条 MyBatis 动态 SQL 中,where 1=1动态拼接 WHERE 条件的经典技巧 ,核心作用是:解决 "第一个动态条件前是否需要加 AND" 的问题,让条件拼接逻辑更简洁、无歧义

一、先看核心问题:没有 1=1 会怎样?

假设去掉 where 1=1,SQL 会变成:

复制代码
where 
<if test="query.shopIdList != null and query.shopIdList.size()>0">
    and a.shopId in (...)
</if>
<if test="query.shopId != null and query.shopId != ''">
    and a.shopId=#{query.shopId}
</if>
...

如果第一个动态条件不满足 (比如 shopIdList 为 null),最终拼接的 SQL 会是:

复制代码
select ... from dws_shop_itemcate_sum a where and a.shopId=xxx

where 后直接跟 and,触发 SQL 语法错误BadSqlGrammarException)。

二、where 1=1 的核心作用

1=1 是一个恒成立的条件(不会过滤任何数据),但它能:

  1. 占住 where 后的第一个位置 ,所有动态条件都可以统一以 and 开头,无需判断 "是不是第一个条件";
  2. 不影响查询结果1=1 永远为真,不会过滤任何数据,最终的查询结果只由后续的动态条件决定;
  3. 简化逻辑 :开发时不用逐个判断 "当前条件是不是第一个",所有动态条件都按 and 条件 写即可,降低出错概率。

三、代码执行示例(更直观)

场景 1:仅传 shopIdList9001,9002

最终拼接的 SQL:

复制代码
select ... from dws_shop_itemcate_sum a 
where 1=1 and a.shopId in (9001,9002)
场景 2:仅传 shopId(9003)+ beginTime(2025-01-01)

最终拼接的 SQL:

复制代码
select ... from dws_shop_itemcate_sum a 
where 1=1 and a.shopId=9003 and a.reportDate>='2025-01-01'
场景 3:不传任何动态条件

最终拼接的 SQL:

复制代码
select ... from dws_shop_itemcate_sum a where 1=1

(等价于 select ... from dws_shop_itemcate_sum a,查询全表)

四、替代方案(MyBatis 更优雅的写法)

MyBatis 提供了 <where> 标签,可以替代 1=1,自动处理多余的 and/or

复制代码
<select id="sumNumberCardDataByShop" resultType="StNumberCardDataBO">
    select 
        <include refid="numberCard_queryColumn"/> 
    from dws_shop_itemcate_sum a  
    <where> <!-- 替代 where 1=1 -->
        <if test="query.shopIdList != null and query.shopIdList.size()>0">
            a.shopId in <!-- 去掉 and -->
            <foreach collection="query.shopIdList" item="shopId"
                index="index" open="(" close=")" separator=",">
                #{shopId}
            </foreach>
        </if>
        <if test="query.shopId != null and query.shopId != ''">
            and a.shopId=#{query.shopId} <!-- 保留 and -->
        </if>
        <if test="query.beginTime != null and  query.beginTime !=''">
            <![CDATA[ and a.reportDate>=#{query.beginTime} ]]>
        </if>
        <if test="query.endTime != null and  query.endTime !=''">
            <![CDATA[ and a.reportDate<=#{query.endTime}]]>
        </if>
    </where>
</select>
<where> 标签的优势:
  • 若有动态条件满足:自动添加 where,并去掉第一个条件前的 and/or
  • 若没有动态条件满足:不生成 where 子句(避免 where 1=1 全表查询);
  • 1=1 更优雅,是 MyBatis 推荐的写法。

五、总结

  1. where 1=1 的本质:用恒真条件占位,让所有动态条件统一以 and 开头,避免语法错误
  2. 优缺点:
    • 优点:简单易懂,新手友好;
    • 缺点:若所有动态条件都不满足,会生成 where 1=1 导致全表查询(可能性能低);
相关推荐
程序员黎剑7 小时前
Spring-Bean生命周期-构造器访问Autowired字段为null
java·后端·spring
sakiko_7 小时前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift
Uncertainty!!7 小时前
Linux 主机无法完成校园网认证排查记录:从 DHCP、ARP 到 Portal 认证流程分析
linux·运维·服务器
迷迭香yy7 小时前
基金档案数据工程实战从收入分析到持仓穿透的Python解析 IG50免费开源股票数据API接口
开发语言·python
古法安卓7 小时前
Android-重启流程源码解析
android·java·android studio
其实防守也摸鱼7 小时前
权限提升与横向移动:从内网渗透到域控的完整技术图谱
运维·服务器·数据库·安全·github·copilot·渗透
清水白石0087 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
人生百态,人生如梦7 小时前
每日论文解读(9.1)——ReToolSQL:面向鲁棒Text-to-SQL的Agentic强化学习与工具增强两阶段训练框架
数据库·sql
DevOpenClub8 小时前
网页采集如何稳定输出结构化数据:JSON、链接与快照三阶段流水线
数据库·json·api
晊晌_h8 小时前
嵌入式从0到精通——线程
java·开发语言·jvm