1.动态SQL介绍:
1.1.动态概念:
- 1.Mybatis框架的动态SQL技术是一种
根据特定条件动态拼装SQL语句的功能
- 2.它存在的意义是
为了解决拼接SQL语句字符串时的痛点问题
1.2.场景举例:
a.批量删除
delete from t_car where id in(1,2,3,4,5,6,......这里的值是动态的,根据用户选择的id不同,值是不同的);
b.多条件查询:
- 1.根据用户的选择进行查询操作,但是选项是不确定有多少的,后台要根据用户的选项进行不同的SQL查询:
select * from t_car where brand like '丰田%' and guide_price > 30 and .....;
2.标签介绍:
2.1.标签if:
a.标签语法:
b.标签说明:
- 1.if标签中
test属性
是必须的。 - 2.if标签中test属性的值是false或者true,
如果test是true,则if标签中的sql语句就会拼接
。反之,则不会拼接。 - 3.test属性中可以使用的是:
- 当
使用了@Param注解
,那么test中要出现的是@Param注解指定的参数名,@Param(“brand”),那么这里只能使用brand
- 当
没有使用@Param注解
,那么test中要出现的是:param1 param2 param3 arg0 arg1 arg2....
- 当使用了POJO,那么test中出现的是POJO类的属性名
- 当
- 4.在mybatis的
动态SQL当中,不能使用&&,只能使用and
c.案例1理解if标签:
- 1.创建接口
- 2.常见接口映射文件:
- 3.测试:
- 4.问题:在映射文件中,当name这个条件不成立的时候,那么此时SQL语句就变成了
select * from ...where and .........
,显然是不行的,所以需要我们再稍微改动下就是加上where 1=1
并且第一个if条件中添加一个and
d.案例2理解if标签:
1.定义接口:
List<Car> selectByMultiCondition(@Param("brand") String brand, @Param("guidePrice") Double guidePrice, @Param("carType") String carType);
2.实现Mapper:
<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>
<if test="carType != null and carType != ''">
and car_type = #{carType}
</if>
</select>
3.测试程序:
@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, "");
// 假设后两个条件不为空,第一个条件为空
//List<Car> cars = mapper.selectByMultiCondition("", 2.0, "新能源");
// 假设第一个条件不是空,后两个条件是空
List<Car> cars = mapper.selectByMultiCondition("比亚迪", null, "");
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
2.2.标签where:
a.标签说明:
- 1.where和
if一般结合使用
: - 2.若where标签中的if
条件都不满足
,则where标签没有任何功能,即不会添加where关键字
- 3.若where标签中的if
条件满足
,则where标签会自动添加where关键字
,并将条件最前方多余的and去掉 - 4.注意:
where标签不能去掉条件最后 多余的and
b.案例1理解:
1.定义接口:
2.映射sql:如下的三种写法都可以,即使多写了and或者or,where都可以给自动的去掉
3.单元测试:
2.3.trim标签:
a.trim标签的四大属性
- prefix:在trim标签中的
内容的前面添加某些内容
- prefixOverrides:在trim标签中的
内容的前面去掉某些内容
- suffix:在trim标签中的
内容的后面添加某些内容
- suffixOverrides:在trim标签中的
内容的后面去掉某些内容
b.标签trim使用案例:
1.定义接口:
2.映射sql:
3.测试:
2.4.set标签:
a.标签说明:
- 1.set标签主要是
用于update语句
中,用来生成set关键字,同时动态去掉最后多余的“,”
- 2.比如我们只更新:
提交字段中的不为空的字段
,如果提交的数据是空值或者"",那么这个字段就不会更新
b.案例理解:
1.定义接口:
未使用set标签来测试更新:
1.映射sql:
2.编写实现类:
使用set表标签来解决上述问题:
1.set标签后的逗号
也会自动的给去掉
2.单元测试
3.测试结果:
2.5.choose、when、otherwise
a.标签说明:
- 1.
choose、when、otherwise相当于if...else if..else;when至少有一个,但是otherwise仅仅只能有一个
b.案例理解choose、when、otherwise:
1.定义接口:
2.映射sql
3.单元测试结果:if…else if…else if…else一样,当有一个条件满足的时候,就走那条道,其他的条件就不会有机会走了,
虽然三个条件都不是空的,但是查询的时候,就只根据第一个不为空的条件来查,后面两个条件都忽略不限制了
如果查询的条件都是空的,那么就会执行otherwise中的语句
2.6.标签foreach:
a.标签说明:
1.属性说明:
- collection:
设置要循环的数组或集合
- item:表示
集合或数组中的每一个数据
- separator:设置
循环体之间的分隔符
- open:设置foreach标签中的内容的
开始符
- close:设置foreach标签中的内容的
结束符
2.接口中要增加
@param
注解,接受传递的数组或者集合变量
b.案例测试:
案例1测试:批量删除
-
1.定义接口:
-
2.映射sql(
两种映射方式
):
-
3.测试:
-
4.测试结果报错了:
报错原因:
-
5.
错误解决办法:添加@param注解解决参数问题(推荐)
或者更改collection参数的值:
案例2测试:批量删除的另一种方式:
- 1.定义接口:
- 2.映射SQL:
- 3.单元测试:
案例3测试:批量插入: 一次插入多条数据:
insert into test(id,name,age) values(1,'sd',20),(2,'ddd',40) ,(3,'sd',20),(4,'ddd',40) ,(1,'sd',20),(1,'ddd',40)
- 1.定义接口:
- 2.映射的sql:
- 3.单元测试:
- 4.查看结果:
2.6.SQL片段
- 1.sql片段,可以
记录一段公共sql片段
,在使用的地方通过include标签
进行引用 - 2.先设置sql片段,然后使用include标签进行引用