【MyBatis】MyBatis操作数据库(二):动态SQL、#{}与${}的区别

news2024/11/24 5:35:01

目录

  • 一、 动态SQL
      • 1.1 \<if>标签
      • 1.2 \<trim>标签
      • 1.3 \<where>标签
      • 1.4 \<set>标签
      • 1.5 \<foreach>标签
      • 1.6 \<include>标签
  • 二、 #{}与${}的区别
      • 2.1 #{}是预编译sql,${}是即时sql
      • 2.2 SQL注入
      • 2.3 #{}性能高于${}
      • 2.4 ${}用于排序功能

一、 动态SQL

什么是动态SQL,简单来说就是为了满足我们的条件可以将不同是SQL语句进行拼接,来使用.

1.1 <if>标签

在我们编程SQL语句中,时常有些参数不知道是否传参,在以往的编程中我们是使用if语句进行判读,在这里也同样如此,只是换成了<if>标签进行判断。
<if>标签的代码如下:

<if test="gender != null">
gender,
</if>

使用<if>标签将我们要判断的内容包裹起来即可。

1.2 <trim>标签

在我们判断的时候,有时会有多余的标点符号或是我们想要在sql语句前添加一下其它关键词,这时候就该<trim>标签派上用场了。
<trim>标签一共有四个属性,记住了属性是添加在<trim 属性>中的,记住添加的位置.
有以下四个属性:

  • prefix:表⽰整个语句块,以prefix的值作为前缀
  • suffix:表⽰整个语句块,以suffix的值作为后缀
  • prefixOverrides:表⽰整个语句块要去除掉的前缀
  • suffixOverrides:表⽰整个语句块要去除掉的后缀

举例代码如下:

<trim prefix="(" suffix=")" suffixOverrides=",">
	<if test="username !=null">
		username,
	</if>
	
	<if test="password !=null">
		`password`,
	</if>
	
	<if test="age != null">
		age,
	</if>
	
	<if test="gender != null">
		gender,
	</if>
	
	<if test="phone != null">
		phone,
	</if>
	
</trim>

可以看到动态SQL是可以一起进行拼接使用的,在举例的该段代码中用到了,prefix用来在前缀添加、suffix用来后缀添加、suffixOverrides用来删除后缀标点,相信举了这个例子另外的的一个predixOverrides也会用了吧!

1.3 <where>标签

在SQL语句中,where关键字一般是用来进行条件判断的,在动态SQL中也是如此,只是我们给它换成<where>的标签形式会更加合理方便
代码如下:

<where>

	<if test="age != null">
		and age = #{age}
	</if>
	
	<if test="gender != null">
		and gender = #{gender}
	</if>
	
	<if test="deleteFlag != null">
		and delete_flag = #{deleteFlag}
	</if>
	
</where>

在动态SQL中使用<where>标签能够在⼦元素有内容的情况下才插⼊where⼦句,⽽且会⾃动去除⼦句的开头的AND或OR

1.4 <set>标签

<set>标签标签一般用在修改数据库的SQL语句中,可以使⽤标签来指定动态内容.
代码如下:

<set>

	<if test="username != null">
		username = #{username},
	</if>
	
	<if test="deleteFlag != null">
		delete_flag = #{deleteFlag},
	</if>

</set>

<set> :动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号.(⽤于update语句中)

1.5 <foreach>标签

对集合进⾏遍历时可以使⽤该标签。标签有如下属性:

• collection:绑定⽅法参数中的集合,如List,Set,Map或数组对象
• item:遍历时的每⼀个对象
•open:语句块开头的字符串
• close:语句块结束的字符串
• separator:每次遍历之间间隔的字符串

代码如下:

<foreach collection="ids" item="id" separator="," open="(" close=")">
	#{id}
</foreach>

使用<foreach>标签就跟使用常见代码中的foreach用法一样,都是用来遍历数组等结构里的每一个元素.

1.6 <include>标签

在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码,而<include>就是将重复的代码提取出来,在后面使用该重复代码中直接拿出来就行了,这里与resultMapper倒是有点相似.

我们可以对重复的代码⽚段进⾏抽取,将其通过 <sql> 标签封装到⼀个SQL⽚段,然后再通过

<include> 标签进⾏引⽤。

<sql> :定义可重⽤的SQL⽚段

<include>:通过属性refid,指定包含的SQL⽚段

展示定义重复的代码-<sql>标签如下:

<sql id="allColumn">
	id, username, age, gender, phone, 
	delete_flag, create_time,update_time
</sql>

使用<include>标签调用已经定义好的代码块如下:

<include refid="allColumn"></include>

通过<sql>标签定义的属性名进行调用.

二、 #{}与${}的区别

MyBatis参数赋值有两种⽅式,咱们前⾯使⽤了 #{} 进⾏赋值,接下来我们看下⼆者的区别

#{}和${}都是在MyBatis操作数据库时进行取值的操作,且两者有以下三点区别,可能平时#{}是用的最多的,但既然${}存在便有其存在的价值和用处。
#{}和${}的区别:

  1. #{}是预编译sql,${}是即时sql

  2. #{}防止了sql注入,而${}可能被sql注入

  3. #{}的缓存性能比${}强大

  4. ${}特殊用处:数据库进行排序…等操作时

2.1 #{}是预编译sql,${}是即时sql

#{}是预编译sql,简单来说就是在程序编译时,用?来作占位符,然后根据传入的参数类型进行填充,如果传入的参数是String类型,则在填充时会自动给数据添加双引号"",来表示该字符串。
sql代码如下:

select username, `password`, age, gender, phone from userinfo where id= ?

在这里插入图片描述
我们输⼊的参数并没有在后⾯拼接,id的值是使⽤ ? 进⾏占位.这种SQL我们称之为"预编译SQL"

然而${}是即时SQL简单来说就是没有占位符,不管你输入的数据是啥,它直接给你填充到参数的位置上去,即使是字符串类型也没有特殊处理,这时为了保证SQL正确,我们要自己手动添加""。
下面是使用${}时的SQL代码:

@Select("select username, `password`, age, gender, phone from userinfo where
id= ${id} ")
UserInfo queryById(Integer id);

代码运行的结果是:
在这里插入图片描述
可以看到,我们输入的参数直接添加到了SQL语句中了,这就是即时SQL-${}

小总结:

从上⾯例⼦可以看出:
#{} 使⽤的是预编译SQL,通过 ? 占位的⽅式,提前对SQL进⾏编译,然后把参数填充到SQL语句中.

#{} 会根据参数类型,⾃动拼接引号"‘’ . ${} 会直接进⾏字符替换,⼀起对SQL进⾏编译.如果参数为字符串,需要加上引号 ‘’ .

2.2 SQL注入

首先来了解一下什么是SQL注入,SQL注入是由于前后端的漏洞而导致的Bug,黑客攻击人员可以通过前端的登录页面将数据输入到数据库,以达到修改甚至是删除数据库的目的。
通过上面学习我们可知,#{}是预编译SQL,而${}是即时SQL,当黑客在前端输入的数据是字符型sql“delete 数据库 ”,如果我们后端是用预编译SQL-#{}来取值的话,系统会看它是字符类型而添加"",进而导致SQL语句错误无法执行。

而使用即时SQL的话,是直接进行SQL拼接,会把delete database数据库直接拼接上去不带引号,这时数据库执行就会成功,把该公司的数据库删除掉。

小总结:

#{}会根据数据类型进行判断是否添加双引号""
KaTeX parse error: Expected 'EOF', got '#' at position 21: …拼接上去,使数据库被黑客攻击 #̲{}能够防止SQL注入,而{}会被SQL注入攻击

2.3 #{}性能高于${}

绝⼤多数情况下,某⼀条SQL语句可能会被反复调⽤执⾏,或者每次执⾏的时候只有个别的值不同(⽐如select的where⼦句值不同,update的set⼦句值不同,insert的values值不同).
如果每次都需要经过上⾯的语法解析,SQL优化、SQL编译等,则效率就明显不⾏了.
在这里插入图片描述
预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译(只是输⼊的参数不同),省去了解析优化等过程,以此来提⾼效率

2.4 ${}用于排序功能

${}会有SQL注⼊的⻛险,所以我们尽量使⽤#{}完成查询,所谓它的存在就有一定的道理,如下在排序时就要用到即时SQL了。

@Select("select id, username, age, gender, phone, delete_flag, create_time,
update_time " +
"from userinfo order by id ${sort} ")
List<UserInfo> queryAllUserBySort(String sort);

使⽤${sort} 可以实现排序查询,⽽使⽤#{sort} 就不能实现排序查询了.
注意:此处sort参数为String类型,但是SQL语句中排序规则是不需要加引号 ‘’ 的,所以此时的${sort} 也不加引号,而使用#{}则会自动添加双引号"",就无法实现排序的功能了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1796311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB基础应用精讲-【数模应用】二元Logit分析(最终篇)(附python、MATLAB和R语言代码实现)

目录 算法原理 SPSSAU 1、二元logistic分析思路说明 2、如何使用SPSSAU进行二元logistic操作 3、二元logistic相关问题 算法流程 一、分析前准备 1、确定分析项 2.多重共线性判断 3.数据预处理 二、回归基本情况分析 三、模型拟合评价 1、似然比检验 2、拟合优…

C语言(数据存储)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#xff0c;在这里撰写成文一…

htb_Mailing

端口扫描 主页有一个download按键 点击后下载了一个pdf 大致看了一下&#xff0c;就是一个使用邮件服务器的说明书 不过最后有一个用户名Maya 目录扫描 /assests/ 一个存图片的地方 /download.php 需要指定下载文件&#xff0c;大概就是刚刚那个pdf 返回主页再次下…

编译等底层知识

目录 一. GCC命令语句大全 二. GCC编译4个阶段 三. makefile的使用 四. CMake 五. GNU工具链开发流程图 六. Keil中的地址段 七. 静态库和动态库 一. GCC命令语句大全 -c只编译源文件&#xff0c;生成目标文件&#xff08;.o 文件&#xff09;&#xff0c;不进行链接。…

学习使用Opentelemetry python SDK

前言 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 一、什么是 OpenTelemetry OpenTelemetry 由 OpenTracing 和 OpenCensus 项目合并而成&#xff0c;是一组规范、工具、API…

DxO ViewPoint v4.8 解锁版安装教程 (校正几何和透视的图像处理)

前言 DxO ViewPoint中文版是一款能够校正几何和透视的图像处理软件,摄影师通过ViewPoint破解版修复构图和光学缺陷并恢复拍摄对象平衡,重新调整如弯曲架构和扭曲图案等细节,让图像具备更强冲击力和更优平衡性。 一、下载地址 下载链接&#xff1a;http://dygod/source 点击搜…

VMware Workstation虚拟机固定IP配置(主机互通、外网可访问)

VMware Workstation虚拟机固定IP配置 环境问题配置过程配置虚拟机网络适配器配置虚拟机网络配置虚拟网卡网络适配器配置虚拟机固定IP 结果验证结束语参考 环境 主机&#xff1a;Windows 11 VMware Workstation: 17.5.2 虚拟机&#xff1a;Ubuntu 24.02 LTS 注&#xff1a; 主…

VRRP----虚拟路由器冗余协议(技术专题)

目录 一、VRRP的基本原理 1.1 技术背景 1.2 VRRP带来了什么 1.2.1 VRRP的作用 1.2.2 VRRP工作的过程 1.2.3 VRRP报文: 1.3 VRRP术语 1.3.1 虚拟IP地址、MAC地址 1.3.2 Master、Backup路由器 二、VRRP的基础配置 实例一 需求 配置 一、VRRP的基本原理 1.1 技术背景…

Spring Cloud工程添加子模块打包后文件为war包而非jar包

Spring Cloud工程添加子模块打包后文件为war包而非jar包 Spring Cloud子模块打出的包通常是JAR包而非WAR包&#xff0c;这是因为Spring Cloud主要基于Spring Boot构建&#xff0c;而Spring Boot默认打包为可执行JAR包。然而&#xff0c;如果遇到了Spring Cloud子模块打成了WAR…

计算机毕业设计Spark+Flink+Hive地铁客流量预测 交通大数据 地铁客流量大数据 交通可视化 大数据毕业设计 深度学习 机器学习

项目说明​ ​ 1该项目主要分析通刷卡数据&#xff0c;通过大数据技术来研究地铁客运能力及探索优化服务的方向​ 2主要讲解Flink流处理实时分析部分&#xff0c;离线部分较简单&#xff0c;暂时略过​ ​ 技术架构​ ​项目流程&#xff1a;​ 采用python请求深圳地铁数…

每天五分钟深度学习:逻辑回归算法的单样本的梯度下降计算

本文重点 上节课我们已经知道了如何利用计算图通过链式法则来求解输出J对变量的梯度或者导数。本节课程我们将通过逻辑回归这一个具体的例子,来演示如何使用计算图完成逻辑回归的梯度下降算法。 逻辑回归 逻辑回归算法的目标函数,损失函数,代价函数,以及参数更新的方式如…

Ffmpeg安装和简单使用

Ffmpeg安装 下载并解压 进入官网 (https://ffmpeg.org/download.html)&#xff0c;选择 Window 然后再打开的页面中下滑找到 release builds&#xff0c;点击 zip 文件下载 环境变量配置 下载好之后解压&#xff0c;找到 bin 文件夹&#xff0c;里面有3个 .exe 文件 然后复制…

度安讲 | 第二期「安全左移·业务护航」技术沙龙成功举办

当下&#xff0c;“安全左移”作为落地DevSecOps的重要实践之一&#xff0c;已在业界达成共识。DevSecOps作为一种集开发、安全、运维于一体的软件开发和运营模式&#xff0c;强调在敏捷交付下&#xff0c;“安全”在软件开发生命周期的全覆盖贯穿和核心位置。所谓“安全左移”…

vue 文件预览mp4、txt、pptx、xls、xlsx、docx、pdf、html、xml

vue 文件预览 图片、mp4、txt、pptx、xls、xlsx、docx、pdf、html、xml 最近公司要做一个类似电脑文件夹的功能&#xff0c;支持文件夹操作&#xff0c;文件操作,这里就不说文件夹操作了&#xff0c;说说文件预览操作&#xff0c;本人是后端java开发&#xff0c;前端vue&#…

gRPC实战 | 实现Python 和 Go 之间的 gRPC 交互

前言 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 一、gRPC 简介 gRPC是一个高性能、通用的开源RPC框架&#xff0c;其由Google主要面向移动应用开发并基于HTTP/2协议标准而设…

eNSP学习——RIP路由协议的汇总

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、配置RIPv1协议 3、配置RIPv2自动汇总 4、配置RIPv2手动汇总 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版_ensp配置命令大全…

Acwing 786.第K个数

Acwing 786.第K个数 题目描述 786. 第k个数 - AcWing题库 运行代码 #include <iostream> #include <algorithm> using namespace std; const int N 100010; int q[N];int main() {int n, k;scanf("%d%d", &n, &k);for (int i 0; i < n; …

网络通讯协议UDP转发TCP工具_UdpToTcpRelay

网络通讯协议UDP转发TCP工具_UdpToTcpRelay 本程序旨在提供一个灵活的、可配置的服务&#xff0c;它处理特定的UDP端口以接收命令&#xff0c;然后将这些命令转换为TCP命令并通过网络发送到指定的TCP服务器【TCP支持十六进制和ASCII】。 此设计特别适用于需要远程控制或自动化…

百度/迅雷/夸克,网盘免费加速,已破!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 之前给大家安利了百度网盘及迅雷的加速方法&#xff0c;详细方法及获取参考之前文章&#xff1a; 刚刚&#xff01;度盘、某雷已破&#xff01;速度50M/s&#xff01; 本次主要介绍夸…

Day23 自定义对话框服务

​本章节实现了,自定义对话框服务的功能 当现有的对话框服务无法满足特定需求时,我们可以采用自定义对话框的解决方案,以更好地满足一些特殊需求。 一.自定义对话框主机服务步骤 在Models 文件夹中,再建立一个 IDialogHostService 接口类,继承自 IDialogService 对话框服…