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…...

ECMAScript6详解
ECMAScript 6,也被称为 ES6 或 ECMAScript 2015,是 JavaScript 编程语言标准的一个主要更新。它于 2015 年正式发布,并带来了许多新特性和改进,使得 JavaScript 开发更加现代化和高效。下面是 ES6 的一些关键特性的详解࿱…...

[C#]使用PaddleInference图片旋转四种角度检测
官方框架地址】 https://github.com/PaddlePaddle/PaddleDetection.git 【算法介绍】 PaddleDetection 是一个基于 PaddlePaddle(飞桨)深度学习框架的开源目标检测工具库。它提供了一系列先进的目标检测算法,包括但不限于 Faster R-CNN, Ma…...

stable diffusion 基础教程-提示词之光的用法
基图 prompt: masterpiece,best quality,1girl,solo,looking at viewer,brown hair,hair between eyes,bangs,very long hair,red eyes,blush,bare shoulders,(white sundress),full body,Negative prompt: EasyNegative,badhandv4,nsfw,lowres,bad anatomy,bad hands,text…...

第9课 回声抑制(AEC+AGC+ANS)的实现
在第8课中,我们将推流端与播放端合并实现了一对一音视频聊天功能,一切看起来还不错。但在实际使用时,会遇到一个烦心的问题:说话时会听到比较大的回声,影响正常使用。所以,这节课我们来重点解决这个问题。 …...

软件测试|Python中的变量与关键字详解
简介 在Python编程中,变量和关键字是非常重要的概念。它们是构建和控制程序的基本要素。本文将深入介绍Python中的变量和关键字,包括它们的定义、使用方法以及一些常见注意事项。 变量 变量的定义 变量是用于存储数据值的名称。在Python中࿰…...

修改安卓apk设置为安卓主屏幕(launcher)
修改安卓apk 将apk可以设置安卓主屏幕 原理: 将打包好的apk文件进行拆包增加配置文件在重新编译回apk包 需要得相关文件下载 解包 apktool :https://pan.baidu.com/s/1oyCIYak_MHDJCvDbHj_qEA?pwd5j2xdex2jar:https://pan.baidu.com/s/1Nc-0vppVd0G…...

unity中 canvas下物体的朝向跟随
public Transform target; private Vector3 direction; void Update() { //第一种 //direction target.position - transform.position; //transform.up -direction.normalized; //第二种 if (target ! null ) { …...

HarmonOS 日期选择组件(DatePicker)
本文 我们一起来看基础组件中的 DatePicker 这就是 日程开发中的日期组件 他可以创建一个日期的范围 并创建一个日期的滑动选择器 这里 我们先写一个组件的骨架 Entry Component struct Index {build() {Row() {Column() {}.width(100%)}.height(100%)} }然后 我们先在Column组…...

linux中的系统安全
一.账号安全 将非登录用户的shell设为/sbin/nologin 系统中用户有三种:超级管理员 普通用户 程序用户 前两种用户可以登录系统,程序用户不给登录 所以称为非登录用户 命令格式: usermod -s /sbin/nologin(改已有用户&#…...

LeetCode(209)长度最小的子数组⭐⭐
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 示例: 输入:s 7, nums [2,3,1,2,4,3]输出:2…...