写在前面
大家好,我是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 | 表示语句以什么结束,通常为’)'右括弧,可选参数 |
index | List中表示当前迭代位置,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
//提交事务
session.commit();
}
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(“等前缀,或者添加”)"等后缀
相关属性
属性 | 描述 |
---|---|
prefix | sql语句拼接的前缀 |
suffix | sql语句拼接的后缀 |
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>
四、总结
基本的内容就总结完毕了,重点在于之后的实践,看完之后记得自己总结下哦,总结出来的东西才是自己的,加油
更多推荐
一步一步学完MyBatis的动态sql标签
发布评论