Javaweb之Mybatis的动态SQL的详细解析
3. Mybatis动态SQL
3.1 什么是动态SQL
在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。
而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字段,其他两个字段 性别 和 入职时间没有传递,那么这两个参数的值就是null。
此时,执行的SQL语句为:
这个查询结果是不正确的。正确的做法应该是:传递了参数,再组装这个查询条件;如果没有传递参数,就不应该组装这个查询条件。
比如:如果姓名输入了"张", 对应的SQL为:
select * from emp where name like '%张%' order by update_time desc;
如果姓名输入了"张",,性别选择了"男",则对应的SQL为:
select * from emp where name like '%张%' and gender = 1 order by update_time desc;
SQL语句会随着用户的输入或外部条件的变化而变化,我们称为:动态SQL。
在Mybatis中提供了很多实现动态SQL的标签,我们学习Mybatis中的动态SQL就是掌握这些动态SQL标签。
3.2 动态SQL-if
<if>
:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。
<if test="条件表达式">要拼接的sql语句
</if>
接下来,我们就通过<if>
标签来改造之前条件查询的案例。
3.2.1 条件查询
示例:把SQL语句改造为动态SQL方式
-
原有的SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">select * from empwhere name like concat('%',#{name},'%')and gender = #{gender}and entrydate between #{begin} and #{end}order by update_time desc
</select>
-
动态SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">select * from empwhere<if test="name != null">name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if>order by update_time desc
</select>
测试方法:
@Test
public void testList(){//性别数据为null、开始时间和结束时间也为nullList<Emp> list = empMapper.list("张", null, null, null);for(Emp emp : list){System.out.println(emp);}
}
执行的SQL语句:
下面呢,我们修改测试方法中的代码,再次进行测试,观察执行情况:
@Test
public void testList(){//姓名为nullList<Emp> list = empMapper.list(null, (short)1, null, null);for(Emp emp : list){System.out.println(emp);}
}
执行结果:
再次修改测试方法中的代码,再次进行测试:
@Test
public void testList(){//传递的数据全部为nullList<Emp> list = empMapper.list(null, null, null, null);for(Emp emp : list){System.out.println(emp);}
}
执行的SQL语句:
以上问题的解决方案:使用<where>
标签代替SQL语句中的where关键字
-
<where>
只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
<select id="list" resultType="com.itheima.pojo.Emp">select * from emp<where><!-- if做为where标签的子元素 --><if test="name != null">and name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc
</select>
测试方法:
@Test
public void testList(){//只有性别List<Emp> list = empMapper.list(null, (short)1, null, null);for(Emp emp : list){System.out.println(emp);}
}
执行的SQL语句:
3.2.2 更新员工
案例:完善更新员工功能,修改为动态更新员工数据信息
-
动态更新员工信息,如果更新时传递有值,则更新;如果更新时没有传递值,则不更新
-
解决方案:动态SQL
修改Mapper接口:
@Mapper
public interface EmpMapper {//删除@Update注解编写的SQL语句//update操作的SQL语句编写在Mapper映射文件中public void update(Emp emp);
}
修改Mapper映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--更新操作--><update id="update">update empset<if test="username != null">username=#{username},</if><if test="name != null">name=#{name},</if><if test="gender != null">gender=#{gender},</if><if test="image != null">image=#{image},</if><if test="job != null">job=#{job},</if><if test="entrydate != null">entrydate=#{entrydate},</if><if test="deptId != null">dept_id=#{deptId},</if><if test="updateTime != null">update_time=#{updateTime}</if>where id=#{id}</update>
</mapper>
测试方法:
@Test
public void testUpdate2(){//要修改的员工信息Emp emp = new Emp();emp.setId(20);emp.setUsername("Tom111");emp.setName("汤姆111");
emp.setUpdateTime(LocalDateTime.now());
//调用方法,修改员工数据empMapper.update(emp);
}
执行的SQL语句:
再次修改测试方法,观察SQL语句执行情况:
@Test
public void testUpdate2(){//要修改的员工信息Emp emp = new Emp();emp.setId(20);emp.setUsername("Tom222");//调用方法,修改员工数据empMapper.update(emp);
}
执行的SQL语句:
以上问题的解决方案:使用<set>
标签代替SQL语句中的set关键字
-
<set>
:动态的在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--更新操作--><update id="update">update emp<!-- 使用set标签,代替update语句中的set关键字 --><set><if test="username != null">username=#{username},</if><if test="name != null">name=#{name},</if><if test="gender != null">gender=#{gender},</if><if test="image != null">image=#{image},</if><if test="job != null">job=#{job},</if><if test="entrydate != null">entrydate=#{entrydate},</if><if test="deptId != null">dept_id=#{deptId},</if><if test="updateTime != null">update_time=#{updateTime}</if></set>where id=#{id}</update>
</mapper>
再次执行测试方法,执行的SQL语句:
小结
-
<if>
-
用于判断条件是否成立,如果条件为true,则拼接SQL
-
形式:
<if test="name != null"> … </if>
-
-
<where>
-
where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
-
-
<set>
-
动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)
-
相关文章:

Javaweb之Mybatis的动态SQL的详细解析
3. Mybatis动态SQL 3.1 什么是动态SQL 在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。 而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面…...

物联网与智能家居:跨境电商与未来生活的融合
物联网(Internet of Things,IoT)和智能家居技术正迅速崛起,成为跨境电商领域的创新引擎。这两者的巧妙结合不仅为消费者提供更智能、便捷的生活方式,同时也为电商平台和制造商带来了全新的商机。本文将深入探讨物联网与…...

Java内存模型(JMM)是基于多线程的吗
Java内存模型(JMM)是基于多线程的吗 这个问题按我的思路转换了下,其实就是在问:为什么需要Java内存模型 总结起来可以由几个角度来看待「可见性」、「有序性」和「原子性」 面试官:今天想跟你聊聊Java内存模型&#…...

Linux离线安装MySQL(rpm)
目录 下载安装包安装MySQL检测安装结果服务启停MySQL用户设置 下载安装包 下载地址:https://downloads.mysql.com/archives/community/ 下载全量包如:(mysql-8.1.0-1.el7.x86_64.rpm-bundle.tar) 解压:tar -xzvf mysql-8.1.0-1.el7.x86_64.…...
用 Socket.D 替代原生 WebSocket 做前端开发
socket.d.js 是基于 websocket 包装的 socket.d 协议的实现。就是用 ws 传输数据,但功能更强大。 功能原生 websocketsocket.d说明listen有有监听消息send有有发消息sendAndRequest无有发消息并接收一个响应(类似于 http)sendAndSubscribe无…...

Transformer架构和对照代码详解
1、英文架构图 下面图中展示了Transformer的英文架构,英文架构中的模块名称和具体代码一一对应,方便大家对照代码、理解和使用。 2、编码器 2.1 编码器介绍 从宏观⻆度来看,Transformer的编码器是由多个相同的层叠加⽽ 成的,每个…...
大数的乘法
题目描述 求两个不超过100位的非负整数的乘积。 输入 有两行,每行是一个不超过100位的非负整数,没有多余的前导0。 输出 一行,相乘后的结果。 样例输入 Copy 123456789 123456789样例输出 Copy 15241578750190521 代码实现࿱…...
年度征文 | 机器学习之心的2023
机器学习之心的2023 2023是极其复杂的一年。 生活上,养了很多宠物。 工作上,写了不少博客。 虽然遇见更多让人不开心的事情,但总体还是美好的。 愿大家新的一年健康平安,生活幸福! 机器学习是一项庞大的工程࿰…...
13.Kubernetes应用部署完整流程:从Dockerfile到Ingress发布完整流程
本文以一个简单的Go应用Demo来演示Kubernetes应用部署的完整流程 1、Dockerfile多阶段构建 Dockerfile多阶段构建 [root@docker github]# git clone https://gitee.com/yxydde/http-dump.git [root@docker github]# cd http-dump/ [root@docker http-dump]# cat Dockerfile …...

多年后再用TB,谈项目管理工具
背景 最近启动一个小项目,多年未曾使用项目管理工具,依稀记得使用过Basecamp,Tower,worktitle,teambition等等,当然还有mantis,vs project等等。于是随便翻阅找个用,不小心翻了TB的牌子,竟然已是阿里旗下的…...

Spark MLlib ----- ALS算法
补充 在谈ALS(Alternating Least Squares)之前首先来谈谈LS,即最小二乘法。LS算法是ALS的基础,是一种数优化技术,也是一种常用的机器学习算法,他通过最小化误差平方和寻找数据的最佳匹配,利用最小二乘法寻找最优的未知数据,保证求的数据与已知的数据误差最小。LS也被用…...

ubuntu桥接方式上网
vmvare:VMware Workstation 17 Pro ubuntu: Ubuntu 14.04.6 LTS window10 下面是我的电脑配置 下面是ubuntu虚拟机的配置 vi /etc/network/interfaces 下面的gateway就是window -ipconfig 截图里的默认网关 auto lo iface lo inet loopbackauto eth0 iface eth0 inet stat…...
收到的字符串写入xml并且将这个xml写入.zip文件中
文章目录 1、将数据写入xml文件WriteToXmlFile2、将xml文件写入zip压缩文件AddToZip3、组合起来4、使用到的头文件和动态库 1、将数据写入xml文件WriteToXmlFile void CSMSLoginDlg::WriteToXmlFile(const std::string& responseData, const std::string& xmlFileName…...

【读书笔记】《白帽子讲web安全》跨站脚本攻击
目录 前言: 第二篇 客户端脚本安全 第3章 跨站脚本攻击(XSS) 3.1XSS简介 3.2XSS攻击进阶 3.2.1初探XSS Payload 3.2.2强大的XSS Payload 3.2.2.1 构造GET与POST请求 3.2.2.2XSS钓鱼 3.2.2.3识别用户浏览器 3.2.2.4识别用户安装的软…...
第九节 初始化项目
系列文章目录 目录 系列文章目录 前言 操作方法 总结 前言 初始化项目,导入默认reset.scss 、variables.scss及mixins.scss等并修改main.js引入样式 操作方法 将默认样式表文件导入到项目。样式文件已经放到资源里请自行下载(...
【论文阅读】深度学习中的后门攻击综述
深度学习中的后门攻击综述 1.深度学习模型三种攻击范式1.1.对抗样本攻击1.2.数据投毒攻击1.3.后门攻击 2.后门攻击特点3.常用术语和标记4.常用评估指标5.攻击设置5.1.触发器5.1.1.触发器属性5.1.2.触发器类型5.1.3.攻击类型 5.2.目标类别5.3.训练方式 1.深度学习模型三种攻击范…...
Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?
在 Spring 中,Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。 在您提供的代码示例中,a1() 和…...
Vue_00001_CLI
初始化脚手架 初始化脚手架步骤: 第一步(仅第一次执行):全局安装vue/cli。 命令:npm install -g vue/cli 第二步:切换到要创建项目的目录,然后使用命令创建项目。 命令:vue creat…...

kubernetes ResourceQuotas Limits(资源配额)
开头语 写在前面:如有问题,以你为准, 目前24年应届生,各位大佬轻喷,部分资料与图片来自网络 内容较长,页面右上角目录方便跳转 简介 当多个用户或团队共享具有固定节点数目的集群时,人们会…...

【ARMv8架构系统安装PySide2】
ARMv8架构系统安装PySide2 Step1. 下载Qt资源包Step2. 配置和安装Qt5Step3. 检查Qt-5.15.2安装情况Step4. 安装PySide2所需的依赖库Step5. 下载和配置PySide2Step6. 检验PySide2是否安装成功 Step1. 下载Qt资源包 if you need the whole Qt5 (~900MB): wget http://master.qt…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...