Mybatis--动态SQL

举报
Java的学习之路 发表于 2022/05/30 20:05:40 2022/05/30
【摘要】  # 前言mybatis的动态sql是一种根据特定的条件来进行动态拼接sql语句的字符串问题,动态 SQL 是 MyBatis 的强大特性之一。使用过 JDBC 或其它类似的框架,大家应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。下面,我就以t_emp表来讲解![在这里插入...

 
# 前言
mybatis的动态sql是一种根据特定的条件来进行动态拼接sql语句的字符串问题,动态 SQL 是 MyBatis 的强大特性之一。使用过 JDBC 或其它类似的框架,大家应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
下面,我就以t_emp表来讲解
![在这里插入图片描述](https://img-blog.csdnimg.cn/349fce2a78e44787a90500ba1251bc74.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_19,color_FFFFFF,t_70,g_se,x_16)

# if标签
 我们在查询数据的时候,一般来说都会根据条件来进行查询,现在我们来根据emp_name和sex来进行数据查询
 先不用动态sql来写
 

```xml
<select id="selectEmpByNameAndSex" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp where emp_name=#{empName} and sex=#{sex}
    </select>
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/3a38b0caf9a44b86a5afb9d5a9bac1bf.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
当我们传入的名字为空的时候,数据就查不出来了

而且以后做项目的时候,通常是由用户在浏览器输入信息,然后后台根据返回的信息进行查询,<font size=4 color="bigresefgrefeqfghrrrrrrrrrrrrrgagaed">我们能不能动态进行查询,也就是说当字段名为null或者等于字符串为空的时候,我们就 不把这个字段作为查询条件
这个时候就得使用动态sql了

我们很容易想到,可以进行判断,如果不满足条件的话,就不作为查询条件,可以用if标签
![在这里插入图片描述](https://img-blog.csdnimg.cn/6b2d4c52343a4553a662140748782082.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/f3c9593cdc0b49bfbfda84c432d7f814.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
但是现在这样写的话,其实是有问题的,如果我们的查询条件都为空,那么在sql语句中where后面就没有任何条件了,这样会报错 ,所以,我们肯定希望where关键字也是动态生成的,如果查询条件不存在,那么where关键字就不写出来。我们可以用where标签来解决。
# if+where 

```xml
 <select id="selectEmpByNameAndSex" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
            <where>
                <if test="empName !=null and empName !=''">
                    emp_name=#{empName}
                </if>
                <if test="sex !=null and sex !=''">
                    and sex=#{sex}
                </if>
            </where>

    </select>
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa7ab75960c94d87bd96054ee89c0585.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)

> <font size=4 color="vaidvjhdsfef">where标签可以动态生成where,而且当where后面直接跟上的是and的话,可以把and给省略掉
>  如果where标签没有任何内容的话,where关键字也不生成        
> 注意:where标签可以自动生成where关键字,并且把内容之前多余的and或者or去掉      
> 当where标签中没有内容时,此时where标签没有任何效果,它不生成where关键字      
> where标签不能把其中内容后面多余的and去掉
![在这里插入图片描述](https://img-blog.csdnimg.cn/2dbe954c30ce49dd8ef92bab001b7a26.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/e5589c12f1d14c1d96ba94789061180b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
# trim标签
trim标签可以代替where
>  <font size=4 color="vaidvjhdsfef"> trim标签:
>    prefix:把trim标签中内容前面添加指定内容
>    suffix:把trim标签中内容后面添加指定内容
>    suffixOverrides:把trim标签中内容后面去掉指定内容
>    prifixOverrides:把trim标签中内容前面去掉指定内容
>     若标签有内容
>          prefix,suffix:可以把trim标签中内容前面或后面添加指定内容
>           suffixOverrides,prefixOverrides:把trim标签中内容前面或后面去掉指定内容
>         若标签没有内容:
>           trim标签也没有任何效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/d13af681b69149edb195233c15ecf159.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeeahOWtpuS5oOS5i-i3rw==,size_20,color_FFFFFF,t_70,g_se,x_16)
# choose(when,otherwise)标签
有的时候,我们并不需要用到所有的查询条件,我们希望只要满足其中一个条件就可以了,我们可以用choose标签来解决,相当于Java的switch case

```xml
<select id="selectEmpByNameAndSex" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
       <where>
          <choose>
              <when test="age !='' and age != null">
                  age=#{age}
              </when>
              <when test="empName !='' and empName != null">
                  and emp_name=#{empName}
              </when>
              <otherwise>
                  and sex=#{sex}
              </otherwise>
          </choose>
      </where>
    </select>
```
使用了choose标签的话,那么只要有一个条件满足,就不会判断其他条件了,所以不需要and,or等关键字

# foreach标签

> <font size=4 color="bigreddafeaegregrwraefafafeagaefdawf">collection:设置需要循环的数组或集合
     item:表示数组或集合中的每一个数据
    separator:循环体之间的分隔符
     open:foreach标签中所循环的所有内容的开始符
   close:foreach标签所循环的所有内容的结束符

foreach很明显就是用来遍历的
比如说我们要查询t_emp表中满足eid在[1,2,3]中的用户
我们有两种方法
①select * from t_emp where eid=1 or eid=2 or eid=3
②select * from t_emp where eid in(1,2,3)
mapper接口定义方法int deleteMore(@Param("eids") Integer[] eids);

<font size=4>**我们用foreach改写select * from t_emp where eid=1 or eid=2 or eid=3**

```xml
 <select id="selectEmpByNameAndSex" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
           <!--
            collection:指定输入对象中的集合属性
            item:每次遍历生成的对象
            open:开始遍历时的拼接字符串
            close:结束时拼接的字符串
            separator:遍历对象之间需要拼接的字符串
            select * from user where 1=1 and (eid=1 or eid=2 or eid=3)
          -->
        <foreach collection="eids" item="eid"   separator="or">
            eid=#{eid}
        </foreach>
    </where>
    </select>
```
 <font size=4>**我们用 foreach 来改写 select * from t_emp where id in (1,2,3)**
 

```xml
 <select id="selectEmpByNameAndSex" resultType="com.atguigu.mybatis.pojo.Emp">
        select * from t_emp
        <where>
            <!--
                collection:指定输入对象中的集合属性
                item:每次遍历生成的对象
                open:开始遍历时的拼接字符串
                close:结束时拼接的字符串
                separator:遍历对象之间需要拼接的字符串
                select * from user where 1=1 and id in (1,2,3)
              -->
            <foreach collection="eids" item="eid" open="eid in (" close=") " separator=",">
                #{eid}
            </foreach>
        </where>
    </select>
```
# sql片段
我们都知道,查询数据库中的数据的时候,最好不要用*,那么我们难道每一次查数据都要把字段一个一个写出来,这样会很麻烦的,为了解决这个问题,我们可以使用sql片段,把我们要查询的字段写在sql片段中,以后要使用的话,直接引用sql片段就可以了。
设置sql片段

```xml
<sql id="empColumns">eid,emp_name,age,sex,email</sql>
```

  引用sql片段

```xml
  select <include refid="empColumns"></include> from t_emp 
```

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。