admin管理员组

文章数量:1794759

一步一步学完MyBatis的动态sql标签

一步一步学完MyBatis的动态sql标签

写在前面 大家好,我是Think-Coder,比较通俗的昵称,寓意是做一个有思考的程序猿,现在的状态是边做项目边学习; 博客是我平时做项目和学习的过程,很基础,但是每一篇我很认真在写,力求让读者,读的清楚,看的明白。 不是大佬,但努力成为,如果您也对Java、算法感兴趣,可以相互关注,一起成长,相信滴水穿石的力量

文章目录
    • 一、基础知识
    • 二、动态sql标签总览
    • 三、动态sql标签详解
      • 3.1 控制sql语句拼接
        • 3.1.1 if标签
        • 3.1.2 choose|when|otherwise标签
        • 3.1.3 foreach标签
      • 3.2 格式化输出
        • 3.2.1 where标签
        • 3.2.2 trim标签
        • 3.2.3 Set标签
      • 3.3 sql片段复用
    • 四、总结

一、基础知识

动态sql是什么

  • 动态SQL指的是事先无法预知具体的条件,需要在运行时根据具体的情况动态地生成SQL语句

动态sql作用

  • 之前的博客主要是增删改查基本操作,当业务变得复杂得时候使用动态sql标签可以减少冗余代码
二、动态sql标签总览

参考了网上大佬的博客,开头的博客已经涉及了前两个分支,接着写向下的分支

本篇博客的练习是基于之前的博客环境搭建,因为Dao层接口和测试类大同小异,所以下面只给出映射文件中的sql语句

三、动态sql标签详解 3.1 控制sql语句拼接 3.1.1 if标签
  • 如:<if test=“address != null”>,test属性判断address字段值是否为空

作用

  • 用于select、insert、update语句中
  • 根据参数判断值判断使用哪个查询条件,是否更新某个字段,是否插入某个字段

举例

<select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User"> select id, username, birthday, sex, address from user where 1=1 <if test="username !=null and username != ''"> //判断username值是否为空 and username like #{username} </if> <if test="address != null"> //判断address值是否为空 and address like #{address} </if> </select>

生成的sql语句 假如username值为空,address值不为空

select id,username,birthday,sex,address from user where 1=1 and address like #{address} 3.1.2 choose|when|otherwise标签

一般这三个标签一起使用,相当于java中switch语句

  • choose为switch
  • when为case
  • otherwise为default

标签执行流程

MyBatis提供choose元素,按顺序判断when中条件是否成立 如果一个成立,choose结束 当when所有的条件都不满足时,则执行otherwise中的sql语句

举例

<select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User"> select id, username, birthday, sex, address from user where 1=1 <choose> <when test="username !=null and username != ''"> and username like #{username} </when> <when test="address != null"> and address like #{address} </when> <otherwise> and sex='男' </otherwise> </choose> </select>

生成的sql语句 假如现在username不为空

select id,username,birthday,sex,address from user where 1=1 and username like #{username}

直接拼接第一个when元素的后面的sql语句,下面的when和otherwise元素不再判断

if和choose标签区别

  • if可以将所有的sql语句拼接起来,choose|when|otherwise只选择其中的一个标签下的sql语句
3.1.3 foreach标签

作用

  • 遍历集合,构建in条件语句或者批量操作语句

标签属性

属性含义
collection表示迭代集合的名称,可以使用@Param注解指定,必选参数
item表示本次迭代获取元素,若collection为List类型,表示其中元素,为map类型表示key-value的value
open表示语句以什么开始,通常为’('左括弧,可选参数
close表示语句以什么结束,通常为’)'右括弧,可选参数
indexList中表示当前迭代位置,Map中表示元素key,可选参数
separator每次迭代后加的字符

参考网上大佬的博客

举例 1.批量插入用户 测试类代码

@Test public void bulkInsertUser(){ List<User> users = new ArrayList<User>(); users.add(new User("赵一",new Date(),"男","河北邯郸")); users.add(new User("钱一",new Date(),"女","河北张家口")); users.add(new User("孙一",new Date(),"男","河北石家庄")); int ids = userDao.bulkInsertUser(users); System.out.println(ids);//3 //提交事务 sessionmit(); }

IUserDao接口

//批量添加用户 //参数users便为collection属性值 int bulkInsertUser(@Param(value = "users") List<User> users);

IUserDao.xml映射文件

<insert id="bulkInsertUser"> insert into user(username,birthday,sex,address) values <foreach collection="users" item="user" index="index" separator=","> (#{user.username},#{user.birthday},#{user.sex},#{user.address}) </foreach> </insert>

生成的sql语句如下

insert into user(username,birthday,sex,address) values ("赵一","2020-06-03 10:47:59","男","河北邯郸"), ("钱一","2020-06-03 10:47:59","女","河北张家口"), ("孙一","2020-06-03 10:47:59","男","河北石家庄")

2.批量查询用户in语句 测试类代码

@Test //用于测试批量查询用户 public void findInIds(){ List<Integer> ids = new ArrayList<Integer>(); ids.add(77); ids.add(78); List<User> users = userDao.findInIds(ids); for(User user : users){ System.out.println(user); } }

IUserDao接口

//批量查询用户 List<User> findInIds(@Param(value = "ids") List<Integer> ids);

IUserDao.xml映射文件

<!--批量查询用户--> <select id="findInIds" resultType="com.thinkcoder.domain.User"> select id, username, birthday, sex, address from user <where> <if test="ids != null and ids.size() > 0"> <foreach collection="ids" open = "id in (" close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>

foreach迭代过程

生成的sql语句

select id, username, birthday, sex, address from user where id in (77,78) 3.2 格式化输出 3.2.1 where标签

作用

  • 防止多余关键字and 或 or 出现

举例

where 1=1 <if test="username !=null and username != ''"> //判断username值是否为空 and username like #{username} </if> <if test="address != null"> //判断address值是否为空 and address like #{address} </if>

此时1=1的作用就是去掉多余的and或or 如果不用1=1的sql语句

where and address like #{address}

where 和 and 关键字一起出现,此时sql语句报错,因此就有了where标签

where标签例子

select id, username, birthday, sex, address from user <where> <if test="username !=null and username != ''"> //判断username值是否为空 and username like #{username} </if> <if test="address != null"> //判断address值是否为空 and address like #{address} </if> </where>

除了where标签,后面的trim标签也可以实现

3.2.2 trim标签

作用

  • 1.去除sql语句中多余的关键字(如,and,or),逗号
  • 2.在sql语句前拼接"where"、“set”、以及"values(“等前缀,或者添加”)"等后缀

相关属性

属性描述
prefixsql语句拼接的前缀
suffixsql语句拼接的后缀
prefixOverrides去除sql语句前面的关键字
suffixOverrides去除sql语句后面的关键字

举例 1.去除多余的and关键字

select id, username, birthday, sex, address from user <trim prefix = "where" prefixOverrides = "and"> <if test="username !=null and username != ''"> //判断username值是否为空 and username like #{username} </if> <if test="address != null"> //判断address值是否为空 and address like #{address} </if> </where>

prefix:加上where的前缀 prefixOverrides = “and”:覆盖where相连的and

2.去除多余的逗号,

<update id="updateUser" parameterType="com.thinkcoder.domain.User"> update user <trim prefix="set" suffixOverrides=","> <if test="username != null and username != ''"> username = #{username}, </if> <if test="sex != null and sex != ''"> sex = #{sex}, </if> </trim> where id=#{id} </update>

如果sex为空则sql语句为

update user set username = #{username},where id=#{id}

此时suffixOverrides=","将set语句后的,去掉

3.2.3 Set标签

作用

  • set标签将多余逗号去掉,一般用于update语句中
<update id="updateUser" parameterType="com.thinkcoder.domain.User"> update user <set> <if test="username != null and username != ''"> username = #{username}, </if> <if test="sex != null and sex != ''"> sex = #{sex}, </if> </set> where id=#{id} </update> 3.3 sql片段复用
  • sql标签:重复的 sql 提取出来
  • include标签:使用sql标签,将重复的sql片段引用起来

举例 sql标签

<!-- 抽取重复的语句代码片段 --> <sql id="defaultSql"> select * from user </sql>

include标签

<!-- 配置查询所有操作 --> <select id="findAll" resultType="user"> <include refid="defaultSql"></include> </select> <!-- 根据 id 查询 --> <select id="findById" resultType="com.thinkcoder.domain.User" parameterType="int"> <include refid="defaultSql"></include> where id = #{uid} </select> 四、总结

基本的内容就总结完毕了,重点在于之后的实践,看完之后记得自己总结下哦,总结出来的东西才是自己的,加油

本文标签: 标签动态mybatisSQL