• Mybatis中where标签和if标签结合使用说明


    由于不小心将and或者or写在了语句后面,导致mybatis无法自主判别,这种问题在新上手的同学中很是常见。下面我们探讨一下,在哪些情况下Mybatis无法判断动态SQL语句中的and或者or

    使用标签

    select筛选出视图对象的参数,用于给前端返回页面参数使用。

    	<sql id="selectFileVo">
            select file_id,
                   uuid,
                   file_name,
                   file_url,
                   status,
                   create_time,
                   update_time
            from file
        </sql>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    以下代码格式是正确,我们先观察下and或者or的位置。

        <select id="selectFileList" parameterType="File" resultMap="FileResult">
            <include refid="selectFileVo"/>
            <where>
                <if test="fileName != null  and fileName != ''">
                    and file_name like concat('%', #{fileName}, '%')
                </if>
                <if test="status != null  and status != ''">
                    and status = #{status}
                </if>
                <if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
                    and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
                </if>
            </where>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    再看一下错误的写法;

        <select id="selectFileList" parameterType="File" resultMap="FileResult">
            <include refid="selectFileVo"/>
            <where>
                <if test="fileName != null  and fileName != ''">
                    file_name like concat('%', #{fileName}, '%') and
                </if>
                <if test="status != null  and status != ''">
                    status = #{status} and 
                </if>
                <if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
                    create_time between #{params.beginCreateTime} and #{params.endCreateTime}
                </if>
            </where>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这时候运行该代码,当beginCreateTimeendCreateTime为空时,我们会发现报错SQL执行异常,原因是where多了一个and

    总结

    标签判断失败后, 标签关键字可以自动去除掉库表字段赋值前面的and,不会去掉语句后面的and关键字,即 标签只会去掉 标签语句中的最开始的and关键字。所以上面的写法(and写在后面)是不符合mybatis规范的。

    不使用标签

    当不使用标签时,正确的写法可以参考以下代码:

    <select id="selectFileList" parameterType="File" resultMap="FileResult">
            <include refid="selectFileVo"/>
            where 1=1 
            <if test="fileName != null  and fileName != ''">
                and file_name like concat('%', #{fileName}, '%')
            </if>
            <if test="status != null  and status != ''">
                and status = #{status}
            </if>
            <if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
                and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
            </if>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此时我们发现and是写在前面的,同时增加了1=1条件。

    如果我们去掉1=1条件,同时去掉第一个标签的and

    <select id="selectFileList" parameterType="File" resultMap="FileResult">
            <include refid="selectFileVo"/>
            where 
            <if test="fileName != null  and fileName != ''">
                file_name like concat('%', #{fileName}, '%')
            </if>
            <if test="status != null  and status != ''">
                and status = #{status}
            </if>
            <if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
                and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
            </if>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这种情况下,当fileName为空时,sql语句中会出现where and这种错误的语法,最终导致sql执行异常。所以正确的代码中,使用1=1条件,当fileName为空时,sql语句就会变成where 1=1 ,后面接不接and都能正确执行。

    在不使用标签的情况下,and写在后面,在where条件最后增加1=1判断,原理和上面一样,这里就不再赘述了。

  • 相关阅读:
    嵌入式应用开发之环境搭建及体验
    ddr4测试-2
    如何选择适合爬虫的动态住宅套餐
    Part2_扩展MATSIM_Subpart4_除个人车外的其他模式_第21章 多模式
    在微服务架构中使用JWT
    使用Golang实现HTTP代理突破IP访问限制
    webpack 压缩图片
    Java刷题day32
    java spring cloud 工程企业管理软件-综合型项目管理软件-工程系统源码
    Unity入门08——核心系统02
  • 原文地址:https://blog.csdn.net/Ber_Bai/article/details/128091211