Mybatis中where标签与if标签结合使用详细说明

作者:鳄鱼儿 时间:2021-07-27 08:15:53 

前言

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

使用<where>标签

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

<sql id="selectFileVo">
       select file_id,
              uuid,
              file_name,
              file_url,
              status,
              create_time,
              update_time
       from file
   </sql>

以下代码格式是正确,我们先观察下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>

再看一下错误的写法;

<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>

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

总结

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

不使用<where>标签

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

<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>

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

如果我们去掉1=1条件,同时去掉第一个<if>标签的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>

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

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

来源:https://blog.csdn.net/Ber_Bai/article/details/128091211

标签:mybatis,where标签,if标签
0
投稿

猜你喜欢

  • spring注解之@Valid和@Validated的区分总结

    2023-11-01 07:51:42
  • java String类常量池分析及"equals"和"==”区别详细介绍

    2021-11-28 01:54:48
  • Jmeter如何添加循环控制器

    2021-06-26 20:09:52
  • Java数据结构之图的路径查找算法详解

    2023-03-27 03:47:11
  • 详解java整合solr5.0之solrj的使用

    2023-07-23 03:12:06
  • Spring Boot中的Properties的使用详解

    2021-07-02 07:25:22
  • 浅谈Java中Spring Boot的优势

    2022-12-25 17:36:52
  • 深入浅析Java反射机制

    2023-11-25 07:02:03
  • Java并发编程示例(八):处理线程的非受检异常

    2022-03-23 14:15:57
  • Java调用Zookeeper的实现步骤

    2022-04-14 17:01:11
  • 关于Java中的try-with-resources语句

    2022-10-21 16:49:54
  • Java常用的八种排序算法及代码实现+图解

    2022-04-09 13:30:06
  • IntelliJ IDEA使用git初始化仓库的使用方法

    2022-05-24 12:37:26
  • C#正则表达式实用大全(建议收藏!)

    2023-08-29 20:23:58
  • Mybatis执行流程、缓存原理及相关面试题汇总

    2022-10-15 23:30:28
  • Java多线程之多种锁和阻塞队列

    2023-09-26 10:31:55
  • Java多线程通信:交替打印ABAB实例

    2022-04-08 06:57:28
  • Android编程获取GPS数据的方法详解

    2023-09-20 16:37:34
  • Android自定义水波纹底部导航的实现

    2022-08-23 13:12:35
  • 为什么mybatis中的SqlSession一定要关闭

    2022-02-24 07:57:11
  • asp之家 软件编程 m.aspxhome.com