• 客观看待mybatis 中使用 where 1=1


    随便一翻,可以看到使用where 1=1 的人很多, 可能这已经是一个编码习惯了。

    那么使用where 1=1 ,会怎么样么 。


    首先,先辟谣。  

     
    where 1=1 不会导致索引失效 !
    where 1=1 不会导致索引失效 !
    where 1=1 不会导致索引失效 !

    客观看待 :

    为什么会去写这个where 1=1 ? 

    WHERE 1=1 

    示例:

    <select id="queryList" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        where 1=1
    
        <if test="type !=null">
            and TYPE = #{type}
        </if>
    </select>

    可能很多人看到这,已经知道,其实mybatis有where 标签是专门用于这种场景的。

    而且绝大多数人都知道where标签,只是还是习惯使用 where 1=1 .

    其实就是两个点 :

    1. 复制粘贴,随便哪个查询都是if 标签, 复制改一改, 为了不报错,加上 where 1=1 ,完事。
    2. 知道mysql 会将接收到的sql 指令做优化,这种where 1=1 是会被优化掉的,所以不影响。

     

    不影响索引命中:

     不使用 where 1=1 ,能够命中索引:


     

     使用 where 1=1 ,一样命中索引:

     

    所以再说一次 :  where 1=1 不会导致索引失效 !

    Mybatis where标签

    示例:

    <select id="queryList" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        <where>
            <if test="type !=null">
                and TYPE = #{type}
            </if>
        </where>
    </select>

     可以看到使用where标签的话,第一个感觉就是,代码顺畅一点,但是多了一个where标签的使用知识需要知道。

    可以看到,我的示例,上面 where标签  里面 的第一个if标签里面 有写 and 。

    这个是没影响的,mybatis也会帮我们做优化,第一个 and这种东西没关系的。

    因为多个if标签同时存在的时候,只要保证触发了的标签  两两之间是用 and 或者 or这些连接起来就行, 第一个会自动优化掉。当然这是mybatis帮我们做的事情。

    我怎么知道?看源码看的 :
    mybatis where标签的源码:

    可以看到代码里面 where标签 只是定义了一下 所谓的前缀list,实际上还是用的super。

    继承的父类,其实就是 trim 标签。
    所以我们使用where标签写的示例,也可以改成使用trim标签 :
     

    <select id="queryList" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        <trim prefix="WHERE" prefixOverrides="AND | OR" >
            <if test="type !=null">
                and TYPE = #{type}
            </if>
        </trim>
        
    </select>

    trim标签 ,也可以瞄一眼源码:

    prefix:给trim标签内sql语句加上前缀
    suffix:给trim标签内sql语句加上后缀
    prefixOverrides:去除多余的前缀内容,如:prefixOverrides=“AND”,去除trim标签内sql语句多余的前缀"AND"
    suffixOverrides:去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","

    那么mybatis怎么去处理这个where标签(包括任何其他标签)的呢? 其实mybatis源码上有相关的测试函数,也可以看的是怎么给我们如何解析where标签,最后拼接成sql的。

    感兴趣的可以自己看看(如果你自己有想法,其实可以自己定义自己的一套规则,反正最终是解析拼接出sql语句。):
     

     值得思考的问题

    扯远了,那么回到正题, 客观看待使用 where 1=1 .

    上面列了一些where标签的源码,为什么我要列这些。

    其实就是为了引出一个值得思考斟酌的问题?

    使用 where 1=1 ,mysql底层会帮我们优化, 不影响索引。

    使用where标签, 则需要 代码层面 帮我们解析。


    那么这样来说,是不是使用where标签,其实也会存在性能问题,毕竟要走代码解析? 

    那么是选择在java代码应用层的解析还是选择 mysql底层的优化呢?


    这个问题留给大家思考。

  • 相关阅读:
    【Flutter】包管理(11)Flutter JSON 反序列化 json_serializable 进阶 自定义序列化、嵌套的 JSON 对象
    首个保险“远程双录”管理办法出台!菊风持续推进金融业布局双录智能化升级
    【毕业设计】基于单片机的无接触测温枪 - MLX90614 红外测温仪 嵌入式 物联网 stm32
    迅为RK3588在 Linux 系统中使用 NPU
    第十七篇-Awesome ChatGPT Prompts-备份-百度翻译
    HZOJ-322: 程序自动分析
    【前端精进之路】JS篇:第2期 数组精讲
    手写一个博客平台 ~ 第五天
    Stream流中的groupingBy分组操作
    AWS DynamoDB AWS CLI操作与编程
  • 原文地址:https://blog.csdn.net/qq_35387940/article/details/125496143