MyBatis04:动态SQL

系列文章目录

MyBatis01:创建、运行、测试一个mybatis项目
MyBatis02:使用MyBatis查询数据
MyBatis03:嵌套查询、嵌套结果、延迟加载
MyBatis04:动态SQL
MyBatis05:类型转换器
MyBatis06:分页插件、MyBatis配置文件中的标签
MyBatis07:MyBatis注解



前言

下面内容主要讲解什么是动态SQL,动态SQL的优势,以及如何使用mybatis框架的一些标签元素,来实现动态SQL。


一、什么是动态SQL

动态SQL就是动态拼接SQL语句。当SQL语句满足某种条件时,才拼接该SQL语句;不满足某种条件时,就不拼接该SQL语句。

二、动态SQL的优势

例如我们要做批量删除,由于要删除的数据的条数不确定,我可以采取这样两种方法来实现删除数据。第一种,在service层调用dao层的方法,每次删除一条数据。第二种,直接在dao层做判断,删除符合条件的所有数据。第一种方法的问题就在于,每调用一次dao层的方法,就需要连接一次数据库。第二种方法只需要连接一次数据库,就可以删除需要删除的全部数据。当数据量大的时候,两种方法的优劣就非常明显了。第二种方法利用的就是动态SQL。

三、动态SQL的标签元素

注意:
①动态SQL标签里不用写ognl表达式,直接写key即可。但SQL语句的字符串里还是需要写ognl表达式的。
②基本数据类型的封装类型在判断时,不仅要判断是否为null,换需要判断是否为默认值

1. if元素

1.1 语法

<if test="判断条件">
     SQL语句
 </if>

if元素是用来对数据添加判断的,test是判断条件,if标签里可以添加SQL语句。

1.2 案例

根据班级编号和学生姓名模糊查询学生信息
dao接口:

List<Student> selectByClassidAndName(@Param("classid") Integer classid, @Param("name") String name);

映射代码:

<select id="selectByClassidAndName" resultType="com.bean.Student">
    select * from student where 1 = 1
    <if test="classid != null and classid > 0">
        and classid = #{classid}
    </if>
    <if test="name != null and name != ''">
        and name like "%"#{name}"%"
    </if>
</select>

只有条件成立时,才会拼接对应的SQL语句

2. choose、when、otherwise元素

2.1 语法

<choose>
    <when test="判断条件1">SQL语句</when>
    <when test="判断条件2">SQL语句</when>
    <otherwise>SQL语句</otherwise>
</choose>

choose、when、otherwise元素是用来实现多重if判断的。

3. where元素

3.1 语法

<where>
	其他标签或SQL语句            
</where>

where元素相当于SQL语句的where,但比where更加智能,通过案例来讲解。

3.2 案例

<select id="selectByClassidAndName" resultType="com.bean.Student">
    select * from student
    <where>
        <if test="classid != null and classid > 0">
            and classid = #{classid}
        </if>
        <if test="name != null and name != ''">
            and name like "%"#{name}"%"
        </if>
    </where>
</select>

这里使用了where元素。在查询条件时,如果条件成立,会自动去除条件里的and,如果所有条件不成立,在查询语句 select * from student 的后面也不会添加where。

4. trim元素

4.1 语法

<trim prefix="要添加前缀" suffix="要添加的后缀" prefixOverrides="前缀如果有该内容,就覆盖掉" suffixOverrides="后缀如果有该内容,就覆盖掉">
    其他标签或SQL语句
</trim>

trim是用来修剪字符串的

4.2 案例

<select id="selectByClassidAndName" resultType="com.bean.Student">
    select * from student
    <trim prefix="where" prefixOverrides="and">
        <if test="classid != null and classid > 0">
            and classid = #{classid}
        </if>
        <if test="name != null and name != ''">
            and name like "%"#{name}"%"
        </if>
    </trim>
</select>

通过班级id和学生姓名查询学生。解释一下这个代码:
在查询语句至少有一个满足的情况下,才追加where。前缀中如果是and,就把and覆盖掉,否则会出现 where and 这样的情况。

5. set元素

5.1 语法

<set>
    其他标签或SQL语句
</set>

set元素相当于SQL语句的set,但比set更智能。

5.2 案例

<update id="updateByPrimaryKeySelective">
        update student
        <set>
            <if test="name != null">
                name = #{name},
            </if>
            <if test="sex != null">
                sex = #{sex},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="age > 0">
                age = #{age},
            </if>
            <if test="classid > 0">
                classid = #{classid}
            </if>
        </set>
        where id = #{id}
    </update>

至少有一个条件满足的时候,update student 后才会有set。而且set标签会自动去掉语句末尾的逗号

6. foreach元素

6.1 语法

<foreach collection="list" item="id" open="(" separator="," close=")">
  #{id}
</foreach>
属性含义/作用
collection获取要循环的数组或集合,通过key获取
itemcollection迭代一个元素就赋给item一个值
open循环开始要添加的内容
separator每次循环用什么分隔
close循环结束要添加什么内容

foreach就是用来循环的

6.2 批量删除

PetMapper.java

//批量删除
    int deleteBatch(List<Integer> ids);

PetMapper.xml

<delete id="deleteBatch">
    delete from student
    <where>
        id in
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </where>
</delete>

如果id在list集合里,那么就删除该编号的学生

PetService.java

int deleteBatch(List<Integer> ids);

PetServiceImpl.java

@Override
    public int deleteBatch(List<Integer> ids) {
        return this.petMapper.deleteBatch(ids);
    }

PetTest

 @Test
    public void deleteBatch() {
        List<Integer> ids = new ArrayList<>();
        ids.add(5);
        ids.add(6);
        System.out.println(this.petService.deleteBatch(ids));
    }

collection补充: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。当然在作为入参时可以使用@Param(“keyName”)来设置键,设置keyName后,list,array将会失效。

forEach参考:
mybatis之foreach用法


补充

  1. 动态SQL的参数需要使用@Param标签来设置key,否则会报找不到getter错误
  2. 日期类型不能和空字符串比较
  3. 更新数据时,set 属性=xxx 需要用「逗号」分割,别忘了
  4. 批量删除时的list集合是通过参数获取的

总结

今天主要学习了动态SQL。了解了动态SQL的优势,以及学习和使用动态SQL的标签元素,以及介绍了相应的案例来加深理解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员_动次动次

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值