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


    最近看几个老项目的SQL条件中使用了1=1,想想自己也曾经这样写过,略有感触,特别拿出来说道说道。

    编写SQL语句就像炒菜,每一种调料的使用都会影响菜品的最终味道,每一个SQL条件的加入也会影响查询的执行效率。那么 1=1 存在什么样的问题呢?为什么又会使用呢?

    为什么会使用 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

    
    <select id="selectUsersByConditions" parameterType="map" resultType="com.example.User">
      SELECT * FROM user
      <where>
        
        <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标签(如 )来构建条件查询。 标签会自动处理首条条件前的 AND 或 OR。当没有满足条件的 或其他条件标签时, 标签内部的所有内容将被忽略,从而不会生成多余的 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语句时也应该避免添加无意义的条件。

    每一行代码都应该有它存在的理由,不要让人和数据库浪费时间在不必要的事情上。

  • 相关阅读:
    MyBatis的缓存
    微信小程序的服务调取
    【sql】sql中true,false 和 null之间and、or运算的理解。
    LCR 175.计算二叉树的深度
    TOGAF10标准读书会第2场活动精彩继续,高光时刻回顾!
    JavaWeb-JSP+Servlet+Mysql实现JavaWeb基础项目
    20230830比赛总结
    QT_C++_多线程
    搭建自己的以图搜图系统 (一):10 行代码以图搜图
    基于Springboot的超市管理系统毕业设计-附源码
  • 原文地址:https://www.cnblogs.com/bossma/p/18024285