MyBatis 多条件查询、动态SQL、多表操作、注解开发,应有尽有,一网打尽!

MyBatis封装了JDBC通过Mapper代理的方式,以前繁琐的操作通过“属性与字段映射”就简单化解,MyBatis的动态SQL完美展现了DBMS的独特魅力。

一、多条件查询

基于Mybatis的多条件查询,是在Mapper代理的映射文件中写上原有的SQL,然后接口中写一个带参的方法即可,就像这样:

图片

相比于原生的JDBC那一套,通过MyBatis确实解决了不少硬编码的问题

但是用户的查询永远是动态的操作,他可能在多个条件中选择其中少量条件进行查询,我们的SQL是死的,而用户需求对应的SQL却是活的,这样就会造成不匹配而形成语法错误

比如,根据这张表,若是要根据部分字段查出整体,我们可以写对应需求的SQL,但是我要是查询的条件变少了或者变多了呢?若用户只想通过一个条件来查询,那么在其他占位符的位置不输入于是成了null,过不了语法自然查不了,还得重新写SQL,多麻烦

图片

这个时候MyBatis的特色就体现出来了——动态SQL。

二、动态SQL

SQL语句会随着用户的输入或者外部条件的变化而变化,则称之为动态SQL。另外,最新 MyBatis 系列面试题整理好了,大家可以在Java面试库小程序在线刷题。

1. if-where

因为采用了Mapper代理开发,我们可以通过写xml的形式来编写我们的SQL,动态SQL的特性也就在这一举动中所蕴育,在原有的Mapper文件里我们进行如下改造,让平平无奇的SQL焕然一新:

<select id="selByCondition" resultMap="rm">
    select *
    from mybatis
    <where>
    <if test="status !=null">
       and STATUS=#{STATUS}
    </if>
    <if test="companyName !=null and companyName !=''">
    and company_name like #{companyName}
    </if>
    <if test="bracdName !=null and bracdName !=''">
    and bracd_name like #{bracdName}
    </if>
    </where>
</select>

<where>标签可以自动帮我们去掉and”,这样,不管查询的条件怎么变,我跟着这个逻辑流程走就不会出现SQL语法毛病而导致查询不出来的毛病啦,因为null的情况已经被if所过滤掉了,真是太哇塞了!

2. choose-when-ortherwise

对于从多个条件中选择一个的单条件查询的场景,利用分支嵌套就可以实现动态选择单条件:

在MyBatis的Mapper代理中,<choose>相当于switch,<when>相当于case

<select id="selByCondition2" resultMap="rm">
    select *
    from mybatis where
    <choose>
        <when test="status !=null">
            STATUS=#{STATUS}
        </when>
        <when test="companyName !=null and companyName !=''">
            company_name like #{companyName}
        </when>
        <when test="bracdName !=null and bracdName !=''">
            bracd_name like #{bracdName}
        </when>
        <otherwise>1=1</otherwise>
    </choose>
</select>

与多条件查询不同的是,SQL语句中只会有一个分支生效

当用户一个条件都不选时,可以在<otherwise>中写上1=1让语法成立,反之,若选择了条件则会返回正常结果。

推荐一个开源免费的 Spring Boot 最全教程:https://github.com/javastacks/spring-boot-best-practice

3. foreach

对于批量删除的场景,传统的方法是通过in关键字结合占位符来确定,就像这样

where id in (?,?,?)

但对于动态的场景,批量的数量永远是不确定的,这就导致还需要去改SQL里的占位符数量啊,又是一件麻烦事

PS:MyBatis会将数组参数封装成一个Map集合,默认情况(K-V)array=数组。

下面使用了@Param注解改变了map集合中默认的key

图片

于是MyBatis中的<foreach>解决了这一麻烦。

本质是通过遍历的形式,批量删除的数据是由id数组或者集合来决定,collection属性决定了要遍历哪个数组/集合,item属性则来存放选出的元素,并把它放在占位符里,separator属性表示分隔符

<delete id="deleteById">
    delete frpm mybatis where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>;
</delete>

有人会问为啥这里只有一个#{id},我的属性字段不止这一个呀?此id非彼id他是一个数组/集合。

posted @ 2022-09-15 17:00  77庁長  阅读(248)  评论(0编辑  收藏  举报