MyBatis动态SQL--if 标签

mybatis动态sql对我们来说是非常常见的,比如在下面这样一个场景中,

我们需要多条件查询,但是查询的条件又不是固定的,是可以动态改变的,那我们就需要用到动态sql去完成。

动态SQL之 if 标签

接下来我们介绍第一个动态sql标签---< if > 标签.

我们模拟这样一个场景:有三个参数,这三个参数可以输入,也可以不输入,其中某个参数如果没有输入的话或者输入为空,这个参数就不加入sql语句的条件判断中。

mapper接口代码如下:

List<Book> findBookBySqlIf(@Param("bname") String bname ,@Param("price") Double price ,@Param("cid") String cid ) ;

这里顺便解释一下Param注解,因为这时多参数里面的内容。

Param注解作用:
  因为这里有多条参数,所以mybatis会将他们存进数组,当在编写sql语句时,我们获取这些参数的方式有三种方式。
  方式一:使用arg0,arg1...注意0就是第一个
  方式二:使用param1,param2...这里1是第一个参数
  但是这两种可读性都比较差,因为我在编写sql语句时,并不知道arg0或者param就是bname书名的意思。我还要回来看参数名才知道
  方式三:@Param("xxx")注解,写在对应的参数的前面,相当与给他取一个别名xxx,这样我们在编写sql语句的时候,就可以直接用见名知意的别名

mapper接口编写完成后,我们接下来在mapper映射文件中编写sql语句如下:

<select id="findBookBySqlIf" resultType="com.feisi.mybatis.pojo.Book">
       select * from t_book where 1=1
         <!--
         1.if标签的test属性时必须的,里面放着判断条件
         2.if标签中test属性的值是fasle或者true
         3.如果test中是true,则将if标签里面的sql语句拼接上去,否则跳过这个if标签中的slq语句
         4.在mybatis动态sql中并且用and
         -->
        <!-- 这里的额判断条件就是参数不能为空,因为为空说明没有输入,那么要是加入sql语句的条件中,那么不管如果如何都查不到任何Book
-->
                <if test="bname != null and bname != ''">
                    and bname like "%"#{bname}"%"
                </if>
                <if test="price != null and price != ''">
                    and price>#{price}
                </if>
                <if test="cid != null and cid != ''">
                    and cid = #{cid}
                </if>
    </select>

 从上面可以看出,if标签的作用就是对输入的参数进行判断,如果满足条件,就把if标签里的sql语句拼接起来 , 否则就跳过这段sql语句。主要为了防止输入的参数表空的时候,如果也把它加入sql语句的判断条件中,会导致查出来的数据为空。

     另外,这里获取参数的语句和前面Param注解呼应,如果前面没有加上Param注解起别名,那么这里的bname,price,cid都要写成arg0 ,arg1 , arg2 或者param1,2,3.。

     最后再来看看测试代码:

package com.feisi.testMybatis;

import com.feisi.mybatis.mapper.BookMapper;
import com.feisi.mybatis.pojo.Book;
import com.feisi.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class BookMapperTest {
    @Test
    public void findBookBySqlIfTest(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
//        假设三个条件都不是空
//        List<Book> books = mapper.findBookBySqlIf("怡宝" ,99.0,"");
//        假设三个条件都是空
//        那么这里就会出现一个问题,因为三个都是空,那么条件全部都没有拼接上去,那么sql语句就变成了:
//        select * from t_book where
//        这样肯定是不行的,因为后面多了一个where,怎么解决呢?
//        我们可以在写sql语句的时候后面加一个恒true条件,比如这样写:
//        select * from t_book where 1=1 , 这样的话同时第一个if标签语句前面也要加上and
        List<Book> books = mapper.findBookBySqlIf("" ,null,"");
        for(Book book : books) System.out.println("查询到:"+book);
        sqlSession.close();
    }
}

 在上一章中的介绍if 标签时,其实我们发现了一个问题,就是当所有条件都为空时,sql语句会多出来一个where,而且有时候会多出来一个and等等。

而where标签的作用就是为了解决这类问题,where 标签可以自动去除多余的where,and,or这类语句,它是专门管理where子句,可以使其更加灵活。

我们继续沿用上一章的if 标签基础上进行更改代码。

mapper接口如下:

//    动态sql--where 标签
    List<Book> findBookBySqlWhere(@Param("bname") String bname ,@Param("price") Double price ,@Param("cid") String cid ) ;

因为在上一章<if>标签中,已经对代码内容解释过了,所以这里就不在赘述代码了。

mapper映射文件的sql语句如下:

<!--    动态sql(where标签)-->
    <select id="findBookBySqlWhere" resultType="com.feisi.mybatis.pojo.Book">
    select * from t_book
      <where>
          <if test="bname != null and bname != ''">
              and bname like "%"#{bname}"%"
          </if>
          <if test="price != null and price != ''">
              and price>#{price}
          </if>
          <if test="cid != null and cid != ''">
              and cid = #{cid}
          </if>
      </where>

这里其他的地方都没有改变,就是将原来的原生where改成了mybatis中的<where>标签,它管理着where标签里面的所有子句。

那么接下来我们对其进行测试代码如下:

 public void findBookBySqlWhereTest(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
//        三个参数都为空时sql语句:select * from t_book
//        他会自动去掉多余出来的where
//        List<Book> books = mapper.findBookBySqlWhere("" ,null,"");

//        第一不为空时的sql语句:select * from t_book WHERE bname like "%"?"%"
//        他会自动去掉第一个多余出来的and
        List<Book> books = mapper.findBookBySqlWhere("怡宝" ,null,"");
        for(Book book : books) System.out.println("查询到:"+book);
        sqlSession.close();
    }

 在上面的测试语句中可以看到,where标签已经帮我自动删除了多余的where,and,当然or也可以去除。

另外需要注意一点就是,where标签它只能去除写在前面的and,如果你把and语句写在后面,比如这样:

<if test="bname != null and bname != ''">
     bname like "%"#{bname}"%" and
</if>

 那么这样的话,where是不能去除多余的and的。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值