SQL中为什么不要使用1=1?

embedded/2024/12/23 5:33:48/

为什么会使用 1=1?

在动态构建SQL查询时,开发者可能会不确定最终需要哪些条件。这时候,他们就会使用“1=1”作为一个始终为真的条件,让接下来的所有条件都可以方便地用“AND”连接起来,就像是搭积木的时候先放一个基座,其他的积木块都可以在这个基座上叠加。

就像下边这样:

SELECT * FROM table WHERE 1=1
<if test="username != null">AND username = #{username}
</if>
<if test="age > 0">AND age = #{age}
</if>

这样就不用在增加每个条件之前先判断是否需要添加“AND”。

1=1 带来的问题

性能问题?

有的同学会担心 1=1 给数据库带来额外的负担,产生性能问题。

这实际上可能不会发生,因为现代数据库的查询优化器已经非常智能,它们通常能够识别出像 1=1 这样的恒真条件,并在执行查询计划时优化掉它们。在许多情况下,即使查询中包含了1=1,数据库的性能也不会受到太大影响,优化器会在实际执行查询时将其忽略。

但是现代优化器虽然很强大,但它们并不是万能的。在某些复杂的查询场景中,即使是简单的 1=1 也可能对优化器的决策造成不必要的影响。

代码质量

我们仍然需要避免在查询中包含 1=1,因为还有以下几点考虑:

  1. 代码清晰性:即使数据库可以优化掉这样的条件,但对于阅读SQL代码的人来说,1=1可能会造成困惑。代码的可读性和清晰性非常重要,特别是在团队协作的环境中。
  2. 习惯养成:即使在当前的数据库系统中1=1不会带来性能问题,习惯了写不必要的代码可能会在其他情况下引入实际的性能问题。比如,更复杂的无用条件可能不会那么容易被优化掉。
  3. 数据库兼容性:不同的数据库管理系统(DBMS)可能有不同的优化器能力。一个系统可能轻松优化掉1=1,而另一个系统则可能不那么高效。编写不依赖于特定优化器行为的SQL语句是一个好习惯。

编写尽可能高效、清晰和准确的SQL语句,不仅有助于保持代码的质量,也让代码具有更好的可维护性和可扩展性。

替代 1=1 的更佳做法

现在开发者普遍使用ORM框架来操作数据库了,还在完全手写拼SQL的同学可能需要反思下了,这里给两个不同ORM框架下替代1=1的方法。

假设我们有一个用户信息表 user,并希望根据传入的参数动态地过滤用户。

首先是Mybatis

<!-- MyBatis映射文件片段 -->
<select id="selectUsersByConditions" parameterType="map" resultType="com.example.User">SELECT * FROM user<where><!-- 使用if标签动态添加条件 --><if test="username != null and username != ''">AND username = #{username}</if><if test="age > 0">AND age = #{age}</if><!-- 更多条件... --></where>
</select>

在 MyBatis 中,避免使用 WHERE 1=1 的典型方法是利用动态SQL标签(如 <if>)来构建条件查询。<where> 标签会自动处理首条条件前的 AND 或 OR。当没有满足条件的 <if> 或其他条件标签时,<where> 标签内部的所有内容将被忽略,从而不会生成多余的 AND 或 WHERE 子句。

再看看 Entity Framework 的方法:

var query = context.User.AsQueryable();
if (!string.IsNullOrEmpty(username))
{query = query.Where(b => b.UserName.Contains(username));
}
if (age>0)
{query = query.Where(b => b.Age = age);
}
var users = query.ToList();

这是一种函数式编程的写法,最终生成SQL时,框架会决定是否在条件前增加AND,而不需要人为的增加 1=1。

总结

“1=1”在SQL语句中可能看起来无害,但实际上它是一种不良的编程习惯,可能会导致性能下降。就像在做饭时不会无缘无故地多加调料一样,我们在编写SQL语句时也应该避免添加无意义的条件。


http://www.ppmy.cn/embedded/31566.html

相关文章

Vue3组合式API + TS项目中手写国际化插件

文章目录 1. 在项目中创建一个国际化插件的文件i18n.ts2. 创建语言模块json3. 注册插件4. 语言切换组件5. 使用插件(ts中使用全局需注意点) 1. 在项目中创建一个国际化插件的文件i18n.ts <!-- plugins/i18n.ts --> export const i18nPlugin {install(app: any, option:…

【数据结构(邓俊辉)学习笔记】列表01——从向量到列表

文章目录 0.概述1. 从向量到列表1.1 从静态到动态1.2 从向量到列表1.3 从秩到位置1.4 列表 2. 接口2.1 列表节点2.1.1 ADT接口2.1.2 ListNode模板类 2.2 列表2.2.1 ADT接口2.2.2 List模板类 0.概述 学习了向量&#xff0c;再介绍下列表。先介绍下列表里的概念和语义&#xff0…

服务网关GateWay原理

文章目录 自动装配核心类GatewayAutoConfigurationDispatcherHandler请求处理阶段apply方法httpHandler#handle方法WebHandler#handle方法DispatchHanlder#handle方法第一步 getHandler获取请求映射第二步 invokeHandler 请求适配第三步 handleResult请求处理总结 上一篇博文我…

【数据库原理及应用】期末复习汇总高校期末真题试卷

试卷 一、填空题 1.________是位于用户与操作系统之间的一层数据管理软件。 2.数据库系统的三级模式结构是指________、________、________。 3.数据库系统的三种数据模型是________ 、________、________。 4.若关系中的某一属性组的值能唯一地标识一个元组&#xff0c;则…

【算法】深度优先搜索岛屿数量

1、题目描述 有一个由0和1组成的二维矩阵&#xff0c;其中1代表陆地&#xff0c;0代表水&#xff0c;岛屿由水平或垂直方向上相邻的陆地连接形成。 假设矩阵的四周均被水包围&#xff0c;请计算岛屿的数量。 输入&#xff1a;matrix [[1,1,0,0],[0,0,1,0],[0,0,0,0],[0,0,1,1],…

WAAP动态安全解决方案

随着企业数字化进程不断加速&#xff0c;应用安全面临多重威胁&#xff0c;新型攻击方式层出不穷&#xff0c;常见的攻击形式包括Web应用攻击、DDoS攻击、API攻击、恶意爬虫攻击等。企业正面临严峻的安全防护挑战&#xff0c;需寻找一个可靠、全面的安全解决方案。在此情况下&a…

Apache SSI远程命令执行漏洞

什么是SSI Apache SSI&#xff08;Server Side Include)&#xff0c;通常称为"服务器端嵌入"或者叫"服务器端包含"&#xff0c;是一种类似于ASP的基于服务器的网页制作技术。默认扩展名是 .stm、.shtm 和 .shtml。 从技术层面来讲&#xff0c;SSI是一种在静…

【C++】深入剖析C++11 initializer_list 新的类功能 可变模板参数

目录 一、std::initializer_list 1、std::initializer_list是什么类型 2、std::initializer_list 的应用场景 ①给自定义容器赋值 ② 传递同类型的数据集合 二、新的类功能 1、默认成员函数 2、关键字default 3、关键字delete 三、可变参数模板 一、std::initialize…