当前位置:网站首页>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
边栏推荐
- C语言 -- 操作符详解
- JS基础--强制类型转换(易错点,自用)
- flink cdc一启动,源端Oracle那台服务器的CPU就飙升到80%以上,会是啥原因呢?
- Do you think border-radius is just rounded corners?【Various angles】
- 2023年PMP考试会用新版教材吗?回复来了!
- 力扣:63. 不同路径 II
- npm安装依赖报错npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfonpm ERR! errno ENOTFOUND
- 深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)
- About yolo7 and gpu
- 8款最佳实践,保护你的 IaC 安全!
猜你喜欢
读者让我总结一波 redis 面试题,现在肝出来了
el-Select 选择器 底部固定
Towards Real-Time Multi-Object Tracking(JDE)
MySQL日志篇,MySQL日志之binlog日志,binlog日志详解
There is an 8 hour difference between the docker installation of mysql and the host.
3面头条,花7天整理了面试题和学习笔记,已正式入职半个月
Towards Real-Time Multi-Object Tracking (JDE)
信息学奥赛一本通 1312:【例3.4】昆虫繁殖
FPGA学习笔记——知识点总结
【一步到位】Jenkins的安装、部署、启动(完整教程)
随机推荐
如何将 DevSecOps 引入企业?
SLSA 框架与软件供应链安全防护
OpenGL绘制圆
MySQL日志篇,MySQL日志之binlog日志,binlog日志详解
Gartner 权威预测未来4年网络安全的8大发展趋势
Chapter 5 C programming expert thinking 5.4 alert Interpositioning of links
一个对象引用的思考
部署LVS-DR群集【实验】
Use Patroni callback script to bind VIP pit
基于gRPC编写golang简单C2远控
关于yolo7和gpu
BFC、IFC、GFC、FFC概念理解、布局规则、形成方法、用处浅析
C Expert Programming Chapter 4 The Shocking Fact: Arrays and pointers are not the same 4.4 Matching declarations to definitions
谷粒商城-基础篇(项目简介&项目搭建)
DataTable使用Linq进行分组汇总,将Linq结果集转化为DataTable
擎朗智能全国研发创新中心落地光谷:去年曾获2亿美元融资
JS基础--强制类型转换(易错点,自用)
MySQL日期函数
有趣的 Kotlin 0x0E:DeepRecursiveFunction
读者让我总结一波 redis 面试题,现在肝出来了