当前位置:网站首页>9、动态SQL
9、动态SQL
2022-08-04 05:24:00 【猿 白】
9、动态SQL
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题。
9.1、if
//根据条件查询员工信息
List<Emp> getEmpByCondition(Emp emp);
<!--
动态SQL:
1. if 通过test属性中的表达式判断标签中的内容是否会拼接到SQL中
-->
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="emp">
select * from t_emp where
<if test="empName != null and empName != ''">
emp_name = #{
empName}
</if>
<if test="age != null and age != ''">
and age = #{
age}
</if>
<if test="gender != null and gender != ''">
and gender = #{
gender}
</if>
</select>
测试:
@Test
public void testGetEmpByCondition(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
Emp emp = new Emp(null, "张三", 18, null);
// for (Emp emp1 : mapper.getEmpByCondition(emp)) {
// System.out.println(emp1);
// }
List<Emp> empByCondition = mapper.getEmpByCondition(emp);
empByCondition.forEach(System.out::println);
}
9.2、where
上述存在bug:
Emp emp = new Emp(null, "", 18, null);
结果为: select * from t_emp where and age = ?
Emp emp = new Emp(null, "", null, null);
结果为:select * from t_emp where
解决办法一:
select * from t_emp where
1=1
加上恒成立条件
<select id="getEmpByCondition" resultType="emp">
select * from t_emp where 1=1
<if test="empName != null and empName != ''">
emp_name = #{
empName}
</if>
<if test="age != null and age != ''">
and age = #{
age}
</if>
<if test="gender != null and gender != ''">
and gender = #{
gender}
</if>
</select>
解决办法二:
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="emp">
select * from t_emp
<where>
<if test="empName != null and empName != ''">
emp_name = #{
empName}
</if>
<if test="age != null and age != ''">
and age = #{
age}
</if>
<if test="gender != null and gender != ''">
and gender = #{
gender}
</if>
</where>
</select>
where和if一般结合使用
:
若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and去掉
注意:where标签不能去掉条件最后多余的and
9.3、trim
存在的bug:
<select id="getEmpByCondition" resultType="emp">
select * from t_emp
<where>
<if test="empName != null and empName != ''">
emp_name = #{
empName} and
</if>
<if test="age != null and age != ''">
age = #{
age} and
</if>
<if test="gender != null and gender != ''">
gender = #{
gender}
</if>
</where>
</select>
Emp emp = new Emp(null, "张三", 18, null);
结果为:select * from t_emp WHERE emp_name = ? and age = ? and
解决办法
<select id="getEmpByCondition" resultType="emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and">
<if test="empName != null and empName != ''">
emp_name = #{
empName} and
</if>
<if test="age != null and age != ''">
age = #{
age} and
</if>
<if test="gender != null and gender != ''">
gender = #{
gender}
</if>
</trim>
</select>
trim用于去掉或添加标签中的内容
常用属性:
prefix:在trim标签中的内容的前面添加某些内容
prefixOverrides:在trim标签中的内容的前面去掉某些内容
suffix:在trim标签中的内容的后面添加某些内容
suffixOverrides:在trim标签中的内容的后面去掉某些内容
9.4、choose、when、otherwise
choose、when、 otherwise相当于if…else if…else
//根据choose来查询员工信息
List<Emp> getEmpByChoose(Emp emp);
<!--List<Emp> getEmpByChoose(Emp emp);-->
<select id="getEmpByChoose" resultType="emp">
select * from t_emp
<where>
<choose>
<when test="empName != null and empName != ''">
emp_name = #{
empName}
</when>
<when test="age != null and age != ''">
age = #{
age}
</when>
<when test="gender != null and gender != ''">
gender = #{
gender}
</when>
</choose>
</where>
</select>
测试
@Test
public void testGetEmpByChoose(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
Emp emp = new Emp(null, "张三", 18, null);
List<Emp> empByCondition = mapper.getEmpByChoose(emp);
empByCondition.forEach(System.out::println);
}
数据结果:
select * from t_emp WHERE emp_name = ?
9.5、foreach
批量添加
//批量添加员工信息
void insertMoreEmp(@Param("emps") List<Emp> emps);
<!--void insertMoreEmp(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreEmp">
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{
emp.empName},#{
emp.age},#{
emp.gender},null)
</foreach>
</insert>
测试:
@Test
public void testInsertMoreEmp(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
Emp emp0 = new Emp(null, "小明0", 18, "男");
Emp emp1 = new Emp(null, "小明1", 18, "男");
Emp emp2 = new Emp(null, "小明2", 18, "男");
List<Emp> emps = Arrays.asList(emp0, emp1, emp2);
mapper.insertMoreEmp(emps);
}
批量删除
//批量删除员工
void deleteMoreEmp(@Param("empIds") Integer[] empIds);
<!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);-->
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in
(
<foreach collection="empIds" item="empId" separator=",">
#{
empId}
</foreach>
)
</delete>
测试
@Test
public void testDeleteMoreEmp(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
Integer[] integers = {
11, 12, 13};
mapper.deleteMoreEmp(integers);
}
改进:
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in
<foreach collection="empIds" item="empId" separator="," open="(" close=")">
#{
empId}
</foreach>
</delete>
改进2:
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in
<foreach collection="empIds" item="empId" separator="or" >
emp_id = #{
empId}
</foreach>
</delete>
9.6、SQL片段
sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
<sql id="empColumns">
emp_id,emp_name,age,gender,dept_id
</sql>
select <include refid="empColumns"></include> from t_emp
总结:
动态SQL:
1. if 通过test属性中的表达式判断标签中的内容是否会拼接到SQL中
2.where
若where标签中有条件成立,会自动生成where关键字
会自动将where标签中的内容前多余的and去掉,但是其中内容后的and不能去掉
若where标签中没有任何一个条件成立,则where没有任何功能
3.trim
prefix、suffix:在标签中内容前面后面添加指定内容
prefixOverrides、suffixOverrides:在标签中内容前面后面去掉指定内容
4.choose、when、otherwise
相当于java中的if····else if···else
when至少有一个,otherwise做多设置一个
5.foreach
collection:设置需要循环的数组或者集合
item:用一个字符串表示数组或者集合中的每一个数据
separator:设置每次循环的数据之间的分隔符
open:循环的所有内容以什么开始
close:循环的所有内容以什么结束
6.sql片段
可以记录一段SQL,在需要使用的<include>
<sql id=“empColumns”>
emp_id,emp_name,age,gender,dept_id
</sql>
select <include refid=“empColumns”></include> from t_emp
边栏推荐
猜你喜欢
触觉智能分享-SSD20X实现升级显示进度条
px、em、rem的区别
嵌入式系统驱动初级【4】——字符设备驱动基础下_并发控制
Teenage Achievement Hackers Need These Skills
Mini program + e-commerce, fun new retail
心余力绌:企业面临的软件供应链安全困境
腾讯136道高级岗面试题:多线程+算法+Redis+JVM
System design. How to design a spike system (full version transfer)
Resolved error: npm WARN config global `--global`, `--local` are deprecated
深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)
随机推荐
C Expert Programming Chapter 4 The Shocking Fact: Arrays and Pointers Are Not the Same 4.5 Other Differences Between Arrays and Pointers
C Expert Programming Chapter 5 Thinking about Linking 5.2 Advantages of Dynamic Linking
【评价类模型】Topsis法(优劣解距离法)
【SemiDrive源码分析】【MailBox核间通信】47 - 分析RPMSG_IPCC_RPC 方式 单次传输的极限大小 及 极限带宽测试
[One step in place] Jenkins installation, deployment, startup (complete tutorial)
你以为border-radius只是圆角吗?【各种角度】
How to view sql execution plan offline collection
px、em、rem的区别
C Expert Programming Chapter 5 Thinking about Chaining 5.6 Take it easy --- see who's talking: take the Turning quiz
深度学习21天——准备(环境配置)
flink cdc一启动,源端Oracle那台服务器的CPU就飙升到80%以上,会是啥原因呢?
JS基础--强制类型转换(易错点,自用)
The Road to Ad Monetization for Uni-app Mini Program Apps: Full Screen Video Ads
C语言 -- 操作符详解
【一步到位】Jenkins的安装、部署、启动(完整教程)
嵌入式系统驱动初级【4】——字符设备驱动基础下_并发控制
震惊,99.9% 的同学没有真正理解字符串的不可变性
Typora 使用保姆级教程 | 看这一篇就够了 | 历史版本已被禁用
How to keep the source code confidential in the development under the burning scenario
Turn: Management is the love of possibility, and managers must have the courage to break into the unknown