当前位置:网站首页>9. Dynamic SQL
9. Dynamic SQL
2022-08-04 05:30:00 【ape white】
9、动态SQL
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题.
9.1、if
//根据条件查询员工信息
List<Emp> getEmpByCondition(Emp emp);
<!--
动态SQL:
1. if 通过testThe expression in the attribute determines whether the content in the tag will be splicedSQL中
-->
<!--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
Add the constant establishment condition
<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 通过testThe expression in the attribute determines whether the content in the tag will be splicedSQL中
2.where
若where标签中有条件成立,会自动生成where关键字
会自动将whereRedundant before the content in the tagand去掉,But after the contentand不能去掉
若whereNone of the conditions in the label are true,则where没有任何功能
3.trim
prefix、suffix:Add the specified content before and after the content in the label
prefixOverrides、suffixOverrides:Remove the specified content before and after the content in the tag
4.choose、when、otherwise
相当于java中的if····else if···else
when至少有一个,otherwisedo one more
5.foreach
collection:设置需要循环的数组或者集合
item:Use a string to represent each item in the array or collection
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
边栏推荐
- 力扣:62.不同路径
- 字节最爱问的智力题,你会几道?
- 深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)
- C Expert Programming Chapter 5 Thinking about Linking 5.1 Libraries, Linking and Loading
- Towards Real-Time Multi-Object Tracking (JDE)
- 解决错误:npm WARN config global `--global`, `--local` are deprecated
- 关于yolo7和gpu
- 基于gRPC编写golang简单C2远控
- Resolved error: npm WARN config global `--global`, `--local` are deprecated
- C专家编程 第4章 令人震惊的事实:数组和指针并不相同 4.5 数组和指针的其他区别
猜你喜欢
Tactile intelligent sharing - SSD20X realizes upgrade display progress bar
System design. Seckill system
Delphi-C端有趣的菜单操作界面设计
MySQL数据库(基础)
数的划分之动态规划
代码重构:面向单元测试
[Cloud Native--Kubernetes] Pod Resource Management and Probe Detection
如何将 DevSecOps 引入企业?
OpenSSF 安全计划:SBOM 将驱动软件供应链安全
嵌入式系统驱动初级【4】——字符设备驱动基础下_并发控制
随机推荐
C专家编程 第5章 对链接的思考 5.3 函数库链接的5个特殊秘密
力扣:746. 使用最小花费爬楼梯
[One step in place] Jenkins installation, deployment, startup (complete tutorial)
Towards Real-Time Multi-Object Tracking (JDE)
12、分页插件
Bolb analysis of image processing (1)
3面头条,花7天整理了面试题和学习笔记,已正式入职半个月
el-Select selector bottom fixed
4.1 声明式事务之JdbcTemplate
9、动态SQL
关于yolo7和gpu
部署LVS-DR群集【实验】
【评价类模型】Topsis法(优劣解距离法)
Use Patroni callback script to bind VIP pit
使用Patroni回调脚本绑定VIP的坑
[Cocos] cc.sys.browserType可能的属性
【一步到位】Jenkins的安装、部署、启动(完整教程)
【SemiDrive源码分析】【MailBox核间通信】47 - 分析RPMSG_IPCC_RPC 方式 单次传输的极限大小 及 极限带宽测试
信息学奥赛一本通 1312:【例3.4】昆虫繁殖
你以为border-radius只是圆角吗?【各种角度】