前言
前面我们已经学习了三层架构、参数接收和统一返回结果。接下来就要进入 MyBatis 中非常常用的一个知识点:动态 SQL。
在项目中,查询条件经常不是固定的。比如员工查询时,前端可能传姓名,也可能传性别,也可能两个都不传。如果我们给每一种情况都单独写一条 SQL,代码会非常混乱。
这时候就可以使用 MyBatis 动态 SQL。
一、为什么需要动态 SQL?
普通 SQL 是固定的:
sql
select * from emp where name like '%张三%' and gender = 1;
但是实际查询时,name 和 gender 可能都不是必传参数。
所以我们希望 SQL 可以根据参数自动变化:
text
传 name:按姓名查
传 gender:按性别查
都传:两个条件一起查
都不传:查询全部
这就是动态 SQL 的作用。
二、if 标签的使用
<if> 用来判断某个条件是否成立。
xml
<select id="list" resultType="com.example.pojo.Emp">
select *
from emp
where
<if test="name != null and name != ''">
name like concat('%', #{name}, '%')
</if>
</select>
这里的意思是:如果 name 不为空,就拼接姓名查询条件。
但是这样写有一个问题:如果 name 为空,SQL 会变成:
sql
select * from emp where
这条 SQL 是错误的,所以还需要配合 <where> 使用。
三、where 标签的使用
<where> 会自动生成 where 关键字,并且会自动去掉多余的 and 或 or。
xml
<select id="list" resultType="com.example.pojo.Emp">
select id, username, name, gender, phone
from emp
<where>
<if test="name != null and name != ''">
name like concat('%', #{name}, '%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
</where>
order by update_time desc
</select>
这样无论前端传几个条件,SQL 都能正常拼接。
四、Controller 层实现
java
@GetMapping
public Result list(String name, Integer gender) {
List<Emp> empList = empService.list(name, gender);
return Result.success(empList);
}
Controller 负责接收前端传来的查询参数,然后调用 Service。
五、Service 层实现
java
@Override
public List<Emp> list(String name, Integer gender) {
return empMapper.list(name, gender);
}
Service 这里没有复杂业务,只是把参数继续传给 Mapper。
六、Mapper 层实现
java
List<Emp> list(String name, Integer gender);
对应 XML:
xml
<select id="list" resultType="com.example.pojo.Emp">
select id, username, name, gender, phone
from emp
<where>
<if test="name != null and name != ''">
name like concat('%', #{name}, '%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
</where>
</select>
这就是最常见的条件查询动态 SQL。
七、foreach 标签的使用
<foreach> 常用于批量删除。
比如前端传来多个 id:
text
ids=1,2,3
Mapper XML 可以这样写:
xml
<delete id="deleteByIds">
delete from emp
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
最终 SQL 类似:
sql
delete from emp where id in (1,2,3);
八、总结
动态 SQL 是 MyBatis 中非常重要的知识点,尤其是在条件查询和批量操作中经常使用。
<if> 用来判断条件是否拼接,<where> 用来自动处理 where 和多余的 and,<foreach> 常用于遍历集合,完成批量删除、批量新增等操作。