当前位置: 首页 > java >正文

面试tips--MyBatis--<where> where 1=1 的区别

1. 两种写法的背景

在动态 SQL 中,经常需要根据条件拼接 WHERE 子句:

  • 如果直接拼接,容易出现 多余的 AND / OR 或者 空 WHERE 的情况。

  • 为了解决这个问题,有两种常见做法:

    • 方式一:写 WHERE 1=1,后续条件都用 AND 拼接。

    • 方式二:使用 MyBatis 的 <where> 标签,它会自动处理 WHERE 和 AND。


2. <where> 的特点

  • <where> 会自动在拼接的第一个条件前加上 WHERE

  • 如果条件前面有多余的 ANDOR,会自动去掉。

  • 如果没有条件,则不会生成 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+ 版本中。

http://www.xdnf.cn/news/19280.html

相关文章:

  • Burgan Bank Türkiye 如何借助 Elastic 改造可观测性和安全性
  • 【LeetCode 热题 100】62. 不同路径——(解法四)组合数学
  • Scikit-learn Python机器学习 - Scikit-learn加载数据集
  • 49.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--Refit跨服务调用
  • Photoshop - Ps Camera Raw 滤镜
  • 爱普生L3255打印机故障记录
  • 算法(②排序算法)
  • 在word以及latex中引用zotero中的参考文献
  • JVM架构图是怎样的?
  • Python - 机器学习:从 “教电脑认东西” 到 “让机器自己学规律”
  • 第7.5节:awk语言 switch 语句
  • Kubernetes 部署与发布完全指南:从 Pod 到高级发布策略
  • Ruoyi-vue-plus-5.x第一篇Sa-Token权限认证体系深度解析:1.3 权限控制与注解使用
  • Python爬虫实战:构建Widgets 小组件数据采集和分析系统
  • c++--线程休眠/sleep
  • springboot提前注册bean
  • react组件
  • 【深度学习新浪潮】有没有什么方法可以将照片变成线描稿,比如日式漫画的那种?
  • Java高并发架构核心技术有哪些?
  • MySQL数据库迁移到KingbaseES完整指南
  • 类和反射的机制
  • Redis桌面客户端
  • Windows驱动开发与双机调试环境[驱动开发环境配置高阶]
  • 使用 Ansible 和 Azure Pipelines 增强您的 DevOps
  • Qt实战:如何打开摄像头并实现视频的实时预览
  • 2025年09月计算机二级Java选择题每日一练——第十二期
  • macOs上ffmpeg带入libx264库交叉编译
  • 【龙泽科技】汽车电气故障诊断仿真教学软件【迈腾380TSI】
  • WebGIS视角:体感温度实证,哪座“火炉”火力全开?
  • centos7中MySQL 5.7.32 到 5.7.44 升级指南:基于官方二进制包的原地替换式升级