为什么需要动态SQL
在一些特殊的业务场景下,需要用户选择某些标签或选项,对搜索的东西进行过滤,更好的完善用户的体验,这个时候童鞋们就需要使用到动态的SQL进行CRUD啦。
1. if标签
package com.powernode.mybatis.mapper;
import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface CarMapper {
/**
* 根据多条件查询
* @param brand
* @param guidePrice
* @return
*/
List<Car> selectByMultiCondition(@Param("brand") String brand, @Param("guidePrice") Double guidePrice);
}
<select id="selectByMultiCondition" resultType="car">
select * from t_car where 1 = 1
<if test="brand != null and brand != ''">
and brand like "%"#{brand}"%"
</if>
<if test="guidePrice != null and guidePrice != ''">
and guide_price > "%"#{guidePrice}"%"
</if>
</select>
package com.powernode.mybatis.test;
import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class CarMapperTest {
@Test
public void testSelectByMultiCondition() {
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
//List<Car> cars = mapper.selectByMultiCondition("比亚迪", 2.0, "新能源");
List<Car> cars = mapper.selectByMultiCondition("", null, "");
for (Car car :
cars) {
System.out.println(car);
}
sqlSession.close();
}
}
where 1 = 1是为了防止当brand和guidePrice都为空的时候出现select * from t_car where
,以及当其中一个为空时出现select * from t_car where and ...
的sql语句错误
注意点:
- if标签中的test属性是必须的,并且test属性的值只能是布尔值
- test属性中可以使用的是:
- 使用@Param注解,那么test中要出现的是@Param注解指定的参数名
- 没有使用@Param注解,那么test中要出现的是arg0 arg1… 或者 param1 param2…
- 使用了POJO类,那么test中出现的是POJO类中的属性名
- 在mybatis的动态SQL中,不能使用&&,只能使用and或or
2. where标签
mybatis为了让sql语句的可读性更强,不再使用1=1
这种多余且并没有什么用处的语句,提供了where标签,让where子句更加动态智能。
上面的sql语句就可以写成下面的形式
<select id="selectByMultiCondition" resultType="car">
select * from t_car
<where>
<if test="brand != null and brand != ''">
and brand like "%"#{brand}"%"
</if>
<if test="guidePrice != null and guidePrice != ''">
and guide_price > "%"#{guidePrice}"%"
</if>
</where>
</select>
- 所有条件都为空时,where标签不会生成where子句
- where标签会自动去除某些条件中前面多余and或or
3. trim标签
在MyBatis中不仅可以使用where标签对where子句进行动态智能控制,使用trim标签同样可以达到预期的结果。
<select id="selectByMultiConditionWithTrim" resultType="car">
select * from t_car
<!--prefix="where" 是在trim标签所有内容的前面添加where-->
<!--suffixOverrides="and|or" 把trim标签中内容的后缀and或or去掉-->
<trim prefix="where" suffix="" prefixOverrides="" suffixOverrides="and|or" >
<if test="brand != null and brand != ''">
brand like "%"#{brand}"%" and
</if>
<if test="guidePrice != null and guidePrice != ''">
guide_price > #{guidePrice}
</if>
</trim>
</select>
trim标签中的属性
属性 | 说明 |
---|---|
prefix | 在trim标签中的sql语句前添加内容 |
suffix | 在trim标签中的sql语句后添加内容 |
prefixOverrides | 删除掉前缀 |
suffixOverrides | 删除掉后缀 |
4. set标签
set标签用在update语句当中,生成set关键字,并且可以去掉最后多余的“,”
<update id="updateBySet">
update t_car
<set>
<if test="carNum !=null and carNum !=''">car_num = #{carNum},</if>
<if test="brand !=null and brand !=''">brand = #{brand},</if>
<if test="guidePrice !=null and guidePrice !=''">guide_price = #{guidePrice},</if>
<if test="produceTime !=null and produceTime !=''">produce_time = #{produceTime},</if>
<if test="carType !=null and carType !=''">car_type = #{carType},</if>
</set>
where id = #{id}
</update>
5.choose when otherwise
<choose>
<when></when>
<when></when>
<otherwise></otherwise>
</choose>
等同于
if(){
}else if(){
}else{
}
其中只有一个分支会被选择,when可以写多个,但是otherwise只能写一个。
<select id="selectByChoose" resultType="car">
select * from t_car
<where>
<choose>
<when test="brand!=null and brand!=''">
brand like "%"#{brand}"%"
</when>
<when test="guidePrice!=null and guidePrice!=''">
guide_price > "%"#{guidePrice}"%"
</when>
<otherwise>
car_type = "%"#{carType}"%"
</otherwise>
</choose>
</where>
</select>
6. foreach标签
MyBatis中的foreach标签用于循环数组或集合,动态的生成sql
批量删除
用in来删除
<delete id="deleteByIds">
delete from t_car where id in(
<foreach collection="ids" item="id" separator="," >
#{id}
</foreach>
)
</delete>
等同于
<delete>
delete from t_car where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
foreach标签中的属性
属性 | 说明 |
---|---|
collection | 指定数组或集合(使用@Param注解时,可以使用@Param注解指定的值) |
item | 代表数组或集合中的元素 |
separator | 循环之间的分隔符 |
open | foreach循环拼接的所有sql语句的最前面以什么开始 |
close | foreach循环拼接的所有sql语句的最后面以什么结束 |
用or来删除
<delete>
delete from t_car where
<foreach collection="ids" item="id" separator="or" >
id=#{id}
</foreach>
</delete>
参考文档:
https://blog.csdn.net/Aibiabcheng/article/details/118423189?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166918824716800215096839%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166918824716800215096839&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-118423189-null-null.142v66control,201v3control,213v2t3_control1&utm_term=%E5%8A%A8%E6%80%81SQL&spm=1018.2226.3001.4187