当前位置:网站首页>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
边栏推荐
- [Cocos 3.5.2]开启模型合批
- 使用Patroni回调脚本绑定VIP的坑
- Redis common interview questions
- C专家编程 第5章 对链接的思考 5.4 警惕Interpositioning
- C专家编程 第5章 对链接的思考 5.3 函数库链接的5个特殊秘密
- 处理List<Map<String, String>>类型
- flink cdc一启动,源端Oracle那台服务器的CPU就飙升到80%以上,会是啥原因呢?
- npm init [email protected] 构建项目报错SyntaxError: Unexpected token ‘.‘解决办法
- npm安装依赖报错npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfonpm ERR! errno ENOTFOUND
- DataTable使用Linq进行分组汇总,将Linq结果集转化为DataTable
猜你喜欢
震惊,99.9% 的同学没有真正理解字符串的不可变性
谷粒商城-基础篇(项目简介&项目搭建)
[Cloud Native--Kubernetes] Pod Resource Management and Probe Detection
编程大杂烩(四)
The symbol table
C1认证之web基础知识及习题——我的学习笔记
[Cocos 3.5.2]开启模型合批
Typora 使用保姆级教程 | 看这一篇就够了 | 历史版本已被禁用
leetcode 12. 整数转罗马数字
Shocked, 99.9% of the students didn't really understand the immutability of strings
随机推荐
基于gRPC编写golang简单C2远控
如何低成本修bug?测试左移给你答案
编程大杂烩(四)
OpenSSF 安全计划:SBOM 将驱动软件供应链安全
What are the functions of mall App development?
C语言 -- 操作符详解
About yolo7 and gpu
C Expert Programming Chapter 5 Thinking about Linking 5.1 Libraries, Linking and Loading
day13--postman接口测试
在被面试官说了无数次后,终于潜下心来整理了一下JVM的类加载器
C专家编程 第5章 对链接的思考 5.2 动态链接的优点
C专家编程 第4章 令人震惊的事实:数组和指针并不相同 4.3 什么是声明,什么是定义
[SemiDrive source code analysis] [MailBox inter-core communication] 47 - Analysis of RPMSG_IPCC_RPC mode limit size of single transmission and limit bandwidth test
信息学奥赛一本通 1312:【例3.4】昆虫繁殖
The difference between px, em, and rem
QT 如何识别文件的编码格式
嵌入式系统驱动初级【4】——字符设备驱动基础下_并发控制
入坑软件测试的经验与建议
附加:对于“与数据表对应的实体类“,【面对MongoDB时,使用的@Id等注解】和【以前面对MySQL时,使用的@Id等注解】,是不同的;
一个对象引用的思考