当前位置: 首页 > news >正文

【Mybatis】4—动态SQL

⭐⭐⭐⭐⭐⭐
Github主页👉https://github.com/A-BigTree
笔记链接👉https://github.com/A-BigTree/Code_Learning
⭐⭐⭐⭐⭐⭐

如果可以,麻烦各位看官顺手点个star~😊

如果文章对你有所帮助,可以点赞👍收藏⭐支持一下博主~😆


文章目录

  • 5 动态SQL
    • 5.1 简介
    • 5.2 `if`和`where`标签
    • 5.3 `set`标签
      • 5.3.1 相关业务举例
      • 5.3.2 实际配置方式
    • 5.4 `trim`标签
    • 5.5 `choose/when/otherwise`标签
    • 5.6 `foreach`标签
      • 5.6.1 批量插入
      • 5.6.2 批量更新
      • 5.6.3 collection属性
    • 5.7 `sql`标签
      • 5.7.1 抽取重复SQL片段
      • 5.7.2 引用已抽取的SQL片段

5 动态SQL

5.1 简介

Mybatis框架的动态SQL技术是一种 根据特定条件动态拼装SQL语句 的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。

MyBatis的一个强大的特性之一通常是它的动态SQL能力。如果你有使用JDBC或其他相似框架的经验,你就明白条件地串联SQL字符串在一起是多么的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态SQL可以彻底处理这种痛苦。

One of the most powerful features of MyBatis has always been its Dynamic SQL capabilities. If you have any experience with JDBC or any similar framework, you understand how painful it is to conditionally concatenate strings of SQL together, making sure not to forget spaces or to omit a comma at the end of a list of columns. Dynamic SQL can be downright painful to deal with.

5.2 ifwhere标签

<!-- List<Employee> selectEmployeeByCondition(Employee employee); -->
<select id="selectEmployeeByCondition" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_salary from t_emp<!-- where标签会自动去掉“标签体内前面多余的and/or” --><where><!-- 使用if标签,让我们可以有选择的加入SQL语句的片段。这个SQL语句片段是否要加入整个SQL语句,就看if标签判断的结果是否为true --><!-- 在if标签的test属性中,可以访问实体类的属性,不可以访问数据库表的字段 --><if test="empName != null"><!-- 在if标签内部,需要访问接口的参数时还是正常写#{} -->or emp_name=#{empName}</if><if test="empSalary &gt; 2000">or emp_salary>#{empSalary}</if><!--第一种情况:所有条件都满足 WHERE emp_name=? or emp_salary>?第二种情况:部分条件满足 WHERE emp_salary>?第三种情况:所有条件都不满足 没有where子句--></where>
</select>

5.3 set标签

5.3.1 相关业务举例

实际开发时,对一个实体类对象进行更新。往往不是更新所有字段,而是更新一部分字段。此时页面上的表单往往不会给不修改的字段提供表单项。

<form action="" method=""><input type="hidden" name="userId" value="5232" />年  龄:<input type="text" name="userAge" /><br/>性  别:<input type="text" name="userGender" /><br/>坐  标:<input type="text" name="userPosition" /><br/><!-- 用户名:<input type="text" name="userName" /><br/>   --><!-- 余  额:<input type="text" name="userBalance" /><br/>--><!-- 等  级:<input type="text" name="userGrade" /><br/>  --><button type="submit">修改</button></form>

例如上面的表单,如果服务器端接收表单时,使用的是User这个实体类,那么userNameuserBalanceuserGrade接收到的数据就是null

如果不加判断,直接用User对象去更新数据库,在Mapper配置文件中又是每一个字段都更新,那就会把userNameuserBalanceuserGrade设置为null值,从而造成数据库表中对应数据被破坏。

此时需要我们在Mapper配置文件中,对update语句的set子句进行定制,此时就可以使用动态SQL的set标签。

5.3.2 实际配置方式

<!-- void updateEmployeeDynamic(Employee employee) -->
<update id="updateEmployeeDynamic">update t_emp<!-- set emp_name=#{empName},emp_salary=#{empSalary} --><!-- 使用set标签动态管理set子句,并且动态去掉两端多余的逗号 --><set><if test="empName != null">emp_name=#{empName},</if><if test="empSalary &lt; 3000">emp_salary=#{empSalary},</if></set>where emp_id=#{empId}<!--第一种情况:所有条件都满足 SET emp_name=?, emp_salary=?第二种情况:部分条件满足 SET emp_salary=?第三种情况:所有条件都不满足 update t_emp where emp_id=?没有set子句的update语句会导致SQL语法错误-->
</update>

5.4 trim标签

使用trim标签控制条件部分两端是否包含某些字符

  • prefix属性:指定要动态添加的前缀;
  • suffix属性:指定要动态添加的后缀;
  • prefixOverrides属性:指定要动态去掉的前缀,使用|分隔有可能的多个值;
  • suffixOverrides属性:指定要动态去掉的后缀,使用|分隔有可能的多个值;
<!-- List<Employee> selectEmployeeByConditionByTrim(Employee employee) -->
<select id="selectEmployeeByConditionByTrim" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_age,emp_salary,emp_genderfrom t_emp<!-- prefix属性指定要动态添加的前缀 --><!-- suffix属性指定要动态添加的后缀 --><!-- prefixOverrides属性指定要动态去掉的前缀,使用“|”分隔有可能的多个值 --><!-- suffixOverrides属性指定要动态去掉的后缀,使用“|”分隔有可能的多个值 --><!-- 当前例子用where标签实现更简洁,但是trim标签更灵活,可以用在任何有需要的地方 --><trim prefix="where" suffixOverrides="and|or"><if test="empName != null">emp_name=#{empName} and</if><if test="empSalary &gt; 3000">emp_salary>#{empSalary} and</if><if test="empAge &lt;= 20">emp_age=#{empAge} or</if><if test="empGender=='male'">emp_gender=#{empGender}</if></trim>
</select>

5.5 choose/when/otherwise标签

在多个分支条件中,仅执行一个。

  • 从上到下依次执行条件判断
  • 遇到的第一个满足条件的分支会被采纳
  • 被采纳分支后面的分支都将不被考虑
  • 如果所有的when分支都不满足,那么就执行otherwise分支
<!-- List<Employee> selectEmployeeByConditionByChoose(Employee employee) -->
<select id="selectEmployeeByConditionByChoose" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_salary from t_empwhere<choose><when test="empName != null">emp_name=#{empName}</when><when test="empSalary &lt; 3000">emp_salary &lt; 3000</when><otherwise>1=1</otherwise></choose><!--第一种情况:第一个when满足条件 where emp_name=?第二种情况:第二个when满足条件 where emp_salary < 3000第三种情况:两个when都不满足 where 1=1 执行了otherwise-->
</select>

5.6 foreach标签

5.6.1 批量插入

<!--collection属性:要遍历的集合item属性:遍历集合的过程中能得到每一个具体对象,在item属性中设置一个名字,将来通过这个名字引用遍历出来的对象separator属性:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符open属性:指定整个循环把字符串拼好后,字符串整体的前面要添加的字符串close属性:指定整个循环把字符串拼好后,字符串整体的后面要添加的字符串index属性:这里起一个名字,便于后面引用遍历List集合,这里能够得到List集合的索引值遍历Map集合,这里能够得到Map集合的key-->
<foreach collection="empList" item="emp" separator="," open="values" index="myIndex"><!-- 在foreach标签内部如果需要引用遍历得到的具体的一个对象,需要使用item属性声明的名称 -->(#{emp.empName},#{myIndex},#{emp.empSalary},#{emp.empGender})
</foreach>

5.6.2 批量更新

上面批量插入的例子本质上是一条SQL语句,而实现批量更新则需要多条SQL语句拼起来,用分号分开。也就是一次性发送多条SQL语句让数据库执行。此时需要在数据库连接信息的URL地址中设置:

atguigu.dev.url=jdbc:mysql://192.168.198.100:3306/mybatis-example?allowMultiQueries=true

对应的foreach标签如下:

<!-- int updateEmployeeBatch(@Param("empList") List<Employee> empList) -->
<update id="updateEmployeeBatch"><foreach collection="empList" item="emp" separator=";">update t_emp set emp_name=#{emp.empName} where emp_id=#{emp.empId}</foreach>
</update>

5.6.3 collection属性

如果没有给接口中List类型的参数使用@Param注解指定一个具体的名字,那么在collection属性中默认可以使用collection或list来引用这个list集合。这一点可以通过异常信息看出来:

Parameter 'empList' not found. Available parameters are [arg0, collection, list]

在实际开发中,为了避免隐晦的表达造成一定的误会,建议使用@Param注解明确声明变量的名称,然后在foreach标签的collection属性中按照@Param注解指定的名称来引用传入的参数。

5.7 sql标签

5.7.1 抽取重复SQL片段

<!-- 使用sql标签抽取重复出现的SQL片段 -->
<sql id="mySelectSql">select emp_id,emp_name,emp_age,emp_salary,emp_gender from t_emp
</sql>

5.7.2 引用已抽取的SQL片段

<!-- 使用include标签引用声明的SQL片段 -->
<include refid="mySelectSql"/>

相关文章:

【Mybatis】4—动态SQL

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…...

事务传播特性和隔离级别

事务的四大特性 1.原子性&#xff08;Atomicity&#xff09;&#xff1a;事务不可再分&#xff0c;要么都执行&#xff0c;要么都不执行。 2.一致性&#xff08;Consistency&#xff09;&#xff1a;事务执行前后&#xff0c;数据的完整性保持一致&#xff0c;即修改前后数据总…...

socket网络编程

端口 &#xff1a;主机上一个应用程序的代号&#xff08;端口不变&#xff09; 为什么不用PID来表示一个应用 因为PID会变化&#xff0c;而端口是不变的 套接字进程间通信——跨越主机 1、主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序&#xff0c;不同…...

IO多路复用机制详解

高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型&#xff0c;常见的IO模型有四种&#xff1a; &#xff08;1&#xff09;同步阻塞IO&#xff08;Blocking IO&#xff09;&#xff1a;即传统的IO模型。 &#xff08;2&#xff09;同步非阻塞IO&#xff08;Non-blo…...

选择一款好用的营销项目管理可以更好帮您解决任何问题

营销项目管理软件哪个好用&#xff1f;使用Zoho Projects营销项目管理软件&#xff0c;您可以从营销活动中获得最佳结果&#xff0c;并获得可执行的见解。Zoho Projects的营销项目管理软件可让您和您的团队全面了解您的所有活动。监控您的社交渠道、跟踪结果并在一处进行交流。…...

计算机网络(第八版)第三章知识总结(期末复习可用)

本笔记来源于博主上课所记笔记整理&#xff0c;可能不全&#xff0c;欢迎大家批评指正&#xff0c;如果觉得有用记得点个赞&#xff0c;给博主点个关注...该笔记将会持续更新...整理不易&#xff0c;希望大家多多点赞。 第一章 第三章 数据链路层 数据链路层属于计算机网络的低…...

VScode配置8086汇编环境

目录 0、感慨 1、VScode的安装 2、下载MASM/TASM插件 3、测试汇编环境 新建文件 汇编文件配置 汇编代码的运行 0、感慨 搭配一个简单些的环境&#xff0c;对于我们汇编的学习很有帮助&#xff0c;在这里又不得不感叹vscode的强大&#xff0c;使用VScodeMASM/TASM插件就…...

银行数字化转型导师坚鹏:银行同业核心产品与营销策略解读

数字化背景下银行同业核心产品与营销策略解读课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a;不清楚银行同业核心产品发展现状&#xff1f;不清楚如何银行同业产品营销策略&#xff1f;不知道如何更好地挖掘他行优质客户&#xff1f; 课…...

在线答题考试小程序源码系统 支持在线刷题+考试二合一+安装部署教程

分享一个在线答题考试小程序源码系统&#xff0c;支持在线刷题考试二合一&#xff0c;程序包含前后端和详细的安装部署教程&#xff0c;可以用来给学生刷题&#xff0c;给员工刷题&#xff0c;给政企员工刷题&#xff0c;万能通用版适合任何行业在线刷题及考试。 系统功能一览&…...

同城跑腿小程序怎么做

随着市场需求越来越大&#xff0c;分工越来明细&#xff0c;很多人看到了跑腿类的商机&#xff0c;特别是学校、小区、商务园等场所。无论是校园跑腿还是社会类跑腿&#xff0c;例中代取快递、代拿包裹、代搬东西上下楼、代排队、帮忙办事、代买东西、代送等等功能都少不了&…...

爬虫逆向学习(五):使用RPC框架serkio解决逆向难题

serkio应用实战前言实战开发多次调用加密方法破解失败如何刷新加密方法同一个浏览器的加密代码如何给不同用户使用注意事项总结前言 最近在工作中遇到了一个反爬虫产品&#xff0c;处于技术能力和新产品迭代更新快的考虑&#xff0c;最后选择使用RPC技术解决问题&#xff0c;因…...

NumPy 秘籍中文第二版:三、掌握常用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍许多常用函数&#xff1a; sqrt()&#xff0c;log()&#xff0c;arange()&#xff0c;astype()和sum()ceil()&#xff0c;modf()&…...

蓝桥杯基础17:BASIC-02试题 序列求和

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 求123...n的值。 输入格式 输入包括一个整数n。 输出格式 输出一行&#xff0c;包括一个整数&#xff0c;表示123...n…...

vue移动端实现vue-pdf在线预览与展示,并且解决页面汉字空白的问题

vue移动端实现pdf的页面在线预览展示&#xff0c;CMapReaderFactory可以解决文字不展示、空白问题 //1、安装依赖vue-pdf npm install --save vue-pdf//2、使用组件 <pdf v-for"i in numPages" ref"pdfs" :src"pdfUrl" :key"i" …...

代码随想录算法训练营第四十九天 | 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

打卡第49天&#xff0c;买卖股票系列了 今日任务 ● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II 121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#x…...

【职场篇】程序员是否吃青春饭?程序员在35岁之后是否需要转行?

你们好 那么众所周知呢像空姐 还有模特这种职业呢 都是吃青春饭的 那么到了一定年龄呢 他们可能就不做这一行了 那么其实程序员这个职业呢 有的人认为他也是吃青春饭的 普遍人都认为呢 如果程序员做到35岁呢 没有转管理岗位 可能以后就没有什么前途了 可能就要考虑换别的行业了…...

( “树” 之 DFS) 226. 翻转二叉树 ——【Leetcode每日一题】

226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[…...

实验7---myBatis和Spring整合

实验七 myBatis和Spring整合 一、实验目的及任务 通过该实验&#xff0c;掌握mybatis和spring整合方法&#xff0c;掌握生成mapper实现类的两种生成方式。 二、实验环境及条件 主机操作系统为Win10&#xff0c;Tomcat,j2sdk1.6或以上版本。 三、实验实施步骤 略 四、实验报告内…...

DJ3-4 传输层(第四节课)

目录 一、TCP 概述 二、TCP 报文段的首部字段格式 三、TCP 往返时延的估计和超时 1. 估计往返时间 2. RTT 估计例子 3. 估计往返时间的偏差 4. 设置重传超时间隔 一、TCP 概述 全双工服务&#xff1a;允许在同一时间同一连接上&#xff0c;数据能够双向传输。注意&#…...

2023爱分析·商业智能应用解决方案市场厂商评估报告:数聚股份

目录 1. 研究范围定义 2. 商业智能应用解决方案市场分析 3. 厂商评估&#xff1a;数聚股份 4. 入选证书 1. 研究范围定义 商业智能&#xff08;BI&#xff09;是在实现数据集成和统一管理的基础上&#xff0c;利用数据存储和处理、分析与展示等技术&#xff0c;满足企…...

Postgresql字符串操作函数

目录 一、基础字符串操作 二、大小写转换 三、空白处理 四、子串提取 五、搜索与定位 六、字符串修改 七、填充与格式化 八、编码转换 九、正则表达式&#xff08;高级匹配&#xff09; 十、其他实用函数 使用技巧&#xff1a; 以下是 PostgreSQL 中最全面的常用字符…...

​​​​​​​6板块公共数据典型应用场景【政务服务|公共安全|公共卫生|环境保护|金融风控|教育科研]

1. 政务服务 1.1 城市规划与管理 公共数据在城市规划与管理中可发挥关键作用。通过汇聚自然资源、建筑物、人口分布等基础数据,构建数字孪生城市模型,辅助城市总体规划编制、决策仿真模拟。在城市基础设施建设、安全运营、应急管理等方面,公共数据也是不可或缺的基础支撑。例…...

Vue中虚拟DOM的原理与作用

绪论 首先我们先了解&#xff0c;DOM&#xff08;Document Object Model&#xff0c;文档对象模型&#xff09; 是浏览器对 HTML/XML 文档的结构化表示&#xff0c;它将文档解析为一个由节点&#xff08;Node&#xff09;和对象组成的树形结构&#xff08;称为 DOM 树&#xf…...

数据库、数据仓库、数据中台、数据湖相关概念

文章目录 序言1数据库&#xff0c;数据仓库&#xff0c;数据中台&#xff0c;数据湖-概念对比释义1.1概念产生的时间顺序1.2在使用功能方面对比1.3在使用工具方面对比 2数据仓库2.1数据仓库的发展阶段2.2 数据仓库的设计2.3数据仓库常用工具&#xff0c;方法2.3.1分析型数据库和…...

debian12拒绝海外ip连接

确保 nftables 已安装&#xff1a; Debian 12 默认使用 nftables 作为防火墙框架。检查是否安装&#xff1a; sudo apt update sudo apt install nftables启用并启动 nftables 服务 sudo systemctl enable nftables sudo systemctl start nftables下载maxmind数据库 将文件解…...

将单体架构项目拆分成微服务时的两种工程结构

一.独立Project 1.示意图 此时我们创建一个文件夹&#xff0c;在这个文件夹中&#xff0c;创建N个Project&#xff0c;每一个Project对应一个微服务&#xff0c;组成我们的最终的项目。 2.特点 适合那种超大型项目&#xff0c;比如淘宝&#xff0c;但管理负担比较重。 二.Mave…...

零基础在实践中学习网络安全-皮卡丘靶场(第十四期-XXE模块)

本期内容涉及到很多前面的内容&#xff0c;因此复习后可以更好的了解本期内容 介绍 XXE -"xml external entity injection"即"xml外部实体注入漏洞"。 概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导…...

服务器中CC攻击的特点有哪些?

CC攻击作为一种常见的网络攻击类型&#xff0c;主要是用来攻击网站页面的&#xff0c;当大量的用户在访问网站的过程中&#xff0c;打开页面的速度会变得比较慢&#xff0c;给数据库造成的压力就越大&#xff0c;CC攻击会消耗大量的服务器资源&#xff0c;给企业带来一定的经济…...

Python60日基础学习打卡Day46

一、 什么是注意力 注意力机制的由来本质是从onehot-elmo-selfattention-encoder-bert这就是一条不断提取特征的路。各有各的特点&#xff0c;也可以说由弱到强。 其中注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器&#xff0c;就像人类视觉会自动忽略背景&…...

UDP 与 TCP 调用接口的差异:面试高频问题解析与实战总结

在日常开发中&#xff0c;我们经常使用封装良好的 TCP 协议栈&#xff0c;比如 HTTP 客户端、Moudou 网络库等&#xff0c;因此很少从“裸 API”角度深入了解 TCP 和 UDP 的套接字调用流程。但在一些系统底层开发或者网络编程面试中&#xff0c;常被问到“TCP 和 UDP 的调用流程…...